Связь «один ко многим» с использованием Sequelize создает больше внешних ключей, чем ожидалось

#mysql #sql #npm #foreign-keys #sequelize.js

#mysql #sql #npm #внешние ключи #sequelize.js

Вопрос:

Я пытался смоделировать некоторые таблицы и их отношения в MySQL для проекта класса с использованием Sequelize. Это работает для всех таблиц, кроме одной, «Сообщений». Он имеет два отношения «один ко многим» с другой таблицей «Пользователи». Определение таблиц показано ниже: Определение таблицы

Чтобы определить это отношение, вам нужно добавить два ненулевых внешних ключа в таблицу «Сообщения», которые ссылаются на «Пользователей». Пока все хорошо.

Следующий шаг — реализовать это с помощью Sequelize:

 db.Message.belongsTo(db.User,{as: 'receivers', foreignKey: {allowNull: false}});
db.Message.belongsTo(db.User,{as: 'transmitters', foreignKey: {allowNull: false}});

db.User.hasMany(db.Message,{as: 'receivers', foreignKey: {allowNull: false}})
db.User.hasMany(db.Message,{as: 'transmitters', foreignKey: {allowNull: false}})
 

Проблема всего этого возникает, когда я проверяю вывод, который Sequelize предоставляет при запуске сервера. Это фактическая команда, которая дается MySQL для создания таблицы «Сообщение». Он создает три внешних ключа, указывающих на «User»: «receiversId», «transmittersId» и «userId». Результат показан ниже:

 Executing (default): CREATE TABLE IF NOT EXISTS `messages` (`id` INTEGER NOT NULL auto_increment , `text` TEXT NOT NULL, `date` DATETIME NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `receiversId` INTEGER NOT NULL, `transmittersId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`receiversId`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, FOREIGN KEY (`transmittersId`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
 

Я пробовал во многих формах, но этот третий внешний «идентификатор пользователя» всегда создается, и я не знаю почему. Есть какие-либо предложения о том, что я делаю не так? Или это просто ошибка от Sequelize? Или я могу просто игнорировать этот «идентификатор пользователя»?

Спасибо.

Ответ №1:

Вам определенно нужно явно указывать столбцы внешнего ключа и одинаковые на обоих концах. А также не путайте псевдонимы для belongsTo и hasMany . Они не должны быть одинаковыми для обоих концов определенной ассоциации:

 db.Message.belongsTo(db.User,{as: 'receiver', foreignKey: {allowNull: false, name: 'receiverId' }});
db.Message.belongsTo(db.User,{as: 'transmitter', foreignKey: {allowNull: false, name: 'transmitterId' }});

db.User.hasMany(db.Message,{as: 'receivedMessages', foreignKey: {allowNull: false, name: 'receiverId' }})
db.User.hasMany(db.Message,{as: 'transmittedMessages', foreignKey: {allowNull: false, name: 'transmitterId' }})
 

Псевдоним — это имя модели, переданное в качестве первого аргумента belongsTo/hasMany , чтобы указать, как эта переданная модель связана с моделью, которая belongsTo/hasMany была вызвана.

Вышеуказанные псевдонимы приведут к получению экземпляров модели с включенными ассоциациями, подобными этому:

 // Message instance
{
  id: 1,
  // other message fields
  receiver: {
    id: 2,
    name: 'John'
  },
  transmitter: {
    id: 3,
    name: 'Luis'
  }
}
// User instance
{
  id: 3,
  name: 'Luis',
  // other user fields
  receivedMessages: [{
    id: 1,
    text: 'Hello'
  }],
  transmittedMessages: [{
    id: 2,
    name: 'Bye'
  }]
}