Эта ошибка произошла из-за синтаксической ошибки в примере кода в учебнике по Sequelize.
Если мы хотим создать правило для внешнего ключа, оно должно ссылаться на первичный ключ таблицы, на которую ссылаются.Проблема заключается в том, что в коде внешний ключ countryCode
пытается сослаться на модель isoCode
из Country
(которая является таблицей countries
в реальной БД MySQL).
const City = sequelize.define('city', { countryCode: Sequelize.STRING });
const Country = sequelize.define('country', { isoCode: Sequelize.STRING });
Country.hasMany(City, {foreignKey: 'countryCode', sourceKey: 'isoCode'});
City.belongsTo(Country, {foreignKey: 'countryCode', targetKey: 'isoCode'});
Вышеуказанный код секвелирования будет преобразован в оператор SQL, как показано ниже:
CREATE TABLE IF NOT EXISTS `countries` (
`id` INTEGER NOT NULL auto_increment ,
`isoCode` VARCHAR(255),
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
PRIMARY KEY (`id`))
ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `cities` (
`id` INTEGER NOT NULL auto_increment ,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NOT NULL,
`countryCode` VARCHAR(255),
PRIMARY KEY (`id`),
FOREIGN KEY (`countryCode`) REFERENCES `countries` (`isoCode`)
ON DELETE SET NULL ON UPDATE CASCADE)
ENGINE=InnoDB;
Чтобы исправить эту синтаксическую ошибку, мы должны сделать isoCode
из City
модели первичным ключом.Давайте исправим код:
const City = sequelize.define('city', { countryCode: Sequelize.STRING})
const Country = sequelize.define('country', {
isoCode: {
type: Sequelize.STRING,
primaryKey: true
}
})
// ... the rest of code followed below
Когда мы исправим определение модели, код будет работать нормально, как мы и ожидали!
Но что мне интересно ... как мог официальный учебник опубликуйте этот код и дайте новичкам просто попробовать его, не зная, что это не сработает.Конечно, кто-то скажет, что это не проблема Sequelize, а проблема понимания SQL.Но все же я думаю, что учебное пособие должно быть исправлено, чтобы избежать этого.
Ограничение этого решения состоит в том, что нет смысла использовать опции sourceKey
и targetKey
, потому чтодаже без них Sequelize автоматически выяснит взаимосвязь и распознает, что является исходным и целевым ключами среди таблиц.
Тем не менее, я не понимаю ... Думаю, сейчас у меня просто естьне использовать опции sourceKey и targetkey.