Mysql
 sql >> база данни >  >> RDS >> Mysql

Прост пример за релация много към много с помощта на Sequelize

Миграции

Предлагам ви да използвате миграции вместо да правите sync() на всеки модел. Има модул - sequelize.cli което ви позволява лесно да управлявате миграциите и семена. Той по някакъв начин налага структура на проекта чрез създаване на файл за инициализация index.js вътре в /models директория на проекта. Предполага се, че всички ваши модели дефиниции ще бъдат в тази директория. Този скрипт преглежда всички файлове на модела (всяка дефиниция на модела е в отделен файл, напр. mentee.js , question.js ) и изпълнява sequelize.import() за да присвоите тези модели към екземпляра на sequelize - това ви позволява да получите достъп до тях по-късно чрез sequelize[modelName] напр. sequelize.question .

Забележка: когато създавате файлове за миграция, не забравяйте за полетата с времеви отпечатъци - createdAt , updatedAt и в крайна сметка deletedAt .

Синхронизиране

Лично аз използвам sync() само когато стартирам тестовете - това може да се покаже в три стъпки

  1. извършете sequelize.sync({ force: true }) за да синхронизирате всички модели
  2. изпълнете някаква база данни seeds (може да се направи и чрез sequelize-cli ),
  3. изпълнете тестове.

Това е много удобно, защото ви позволява да почистите базата данни преди стартиране на тестове и, за да разграничите разработката от тестовете, тестовете могат да използват различна база данни, напр. project_test , така че базата данни за разработка да остане непокътната.

Много към много

Сега нека да преминем към вашия проблем - m:n връзка между два модела. На първо място, поради факта, че изпълнявате Promise.all() , sync може да работи в различен ред от този, който добавяте функциите в него. За да избегнете тази ситуация, ви предлагам да използвате mapSeries функция на Bluebird обещание, което Sequelize използва и излага под sequelize.Promise (това е и причината за последната ви грешка при изтриването на родителски ред - опитвате се да изтриете mentees който се препраща от menteequestion ).

sequelize.Promise.mapSeries([
    Mentee.sync({ force: true })
  , Question.sync({ force: true })
  , MenteeQuestion.sync({ force: true })
], (model) => { return model.destroy({ where: {} }); }).then(() => {

});

Първи параметър на mapSeries е масив от обещания, но вторият е функция, която се изпълнява с резултата от всяко предварително дефинирано обещание. Поради факта, че Model.sync() резултати в самия модел, можем да изпълним model.destroy() при всяка итерация.

След това можете да вмъкнете някои данни в базата данни чрез create() , точно както в примера. Сега е време да поправите Грешката:наставляваният не е свързан с въпрос на менте! грешка. Това се случва, защото сте свързали Mentee с Question но няма връзка между MenteeQuestion и Mentee (или Question ). За да поправите това, след belongsToMany , можете да добавите

MenteeQuestion.belongsTo(Mentee, { foreignKey: 'menteeId' });
MenteeQuestion.belongsTo(Question, { foreignKey: 'questionId' });

Сега можете да добавите include: [Mentee, Question] при запитване на MenteeQuestion . Вие също ще стартирате при друга грешка, докато правите toJSON() , защото правите findAll който връща масив от екземпляри. Можете да направите forEach()

menteeQuestions.forEach(menteeQuestion => {
    console.log(menteeQuestion.toJSON());
});



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JSON_QUOTE() – Как да избягвате символи в низове, използвани като JSON стойности в MySQL

  2. Защо не трябва да използвате CONCAT() за статични низови литерали?

  3. Класиране на играчите по категории за месеци

  4. INSERT в DB DateTime низ

  5. Съхранени процедури срещу тригери в MySQL