#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'
}]
}