Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Prosty przykład relacji wiele-do-wielu przy użyciu Sequelize

Migracje

Proponuję użyć sequelize migracje zamiast tego robi sync() na każdym modelu. Istnieje moduł - sequelize.cli co pozwala łatwo zarządzać migracjami i seedami. W pewien sposób wymusza to strukturę projektu, tworząc plik inicjujący index.js wewnątrz /models katalog projektu. Zakłada, że ​​wszystkie definicje modeli będą znajdować się w tym katalogu. Ten skrypt iteruje przez wszystkie pliki modeli (każda definicja modelu znajduje się w osobnym pliku, np. mentee.js , question.js ) i wykonuje sequelize.import() w celu przypisania tych modeli do instancji sequelize - to pozwala na późniejszy dostęp do nich poprzez sequelize[modelName] np. sequelize.question .

Uwaga: podczas tworzenia plików migracji pamiętaj o polach znaczników czasu - createdAt , updatedAt i ostatecznie deletedAt .

Synchronizacja

Osobiście używam sync() tylko wtedy, gdy uruchamiam testy - można to pokazać w trzech krokach

  1. wykonaj sequelize.sync({ force: true }) w celu synchronizacji wszystkich modeli
  2. uruchom trochę bazy danych seeds (można również zrobić przez sequelize-cli ),
  3. przeprowadź testy.

Jest to bardzo wygodne, ponieważ pozwala wyczyścić bazę danych przed uruchomieniem testów, a w celu odróżnienia programowania od testów, testy mogą korzystać z innej bazy danych, m.in. project_test , dzięki czemu baza danych rozwoju pozostaje nienaruszona.

Wiele do wielu

Przejdźmy teraz do Twojego problemu - relacji m:n między dwoma modelami. Przede wszystkim ze względu na to, że wykonujesz Promise.all() , sync może działać w innej kolejności niż dodajesz w nim funkcje. Aby uniknąć tej sytuacji, sugeruję użycie mapSeries funkcja Bluebird obietnica, której Sequelize używa i ujawnia w sequelize.Promise (jest to również powód twojego ostatniego błędu dotyczącego usuwania wiersza nadrzędnego - próbujesz usunąć mentees do którego odwołuje się menteequestion ).

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

});

Pierwszy parametr mapSeries to tablica obietnic, natomiast druga to funkcja uruchamiana z wynikiem każdej wcześniej zdefiniowanej obietnicy. Ze względu na fakt, że Model.sync() wyniki w samym modelu, możemy wykonać model.destroy() w każdej iteracji.

Następnie możesz wstawić niektóre dane do bazy danych za pomocą create() , tak jak w przykładzie. Czas naprawić Błąd:podopieczny nie jest powiązany z podopiecznym! błąd. Dzieje się tak, ponieważ powiązałeś Mentee z Question ale nie ma powiązania między MenteeQuestion i Mentee (lub Question ). Aby to naprawić, po belongsToMany , możesz dodać

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

Teraz możesz dodać include: [Mentee, Question] podczas zapytania MenteeQuestion . Uruchomiłbyś również inny błąd podczas wykonywania toJSON() , ponieważ robisz findAll co zwraca tablicę instancji. Możesz zrobić 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. Czy ten diagram ER powinien zamiast tego używać relacji trójskładnikowej?

  2. Jak używać instrukcji IF w kwerendzie sprzężenia MySQL?

  3. Laravel 5.3 Tworzenie modeli Pole zwraca nie ma wartości domyślnej

  4. Przywracanie bazy danych mysql powoduje błędy

  5. Jak naprawić wyjątek 'java.lang.ClassNotFoundException:com.mysql.jdbc.Driver' po dodaniu go do ścieżki budowania i zarejestrowaniu przy użyciu Class.forName();