(Добавлен SQL) Sequelize hasMany ассоциации с опцией - PullRequest
0 голосов
/ 04 января 2019

Я новичок в Sequelize, и я учусь на официальном сайте учебника (http://docs.sequelizejs.com/manual/tutorial/). Я застрял при попытке выполнить код из учебника.

Код, который я пробовал, был таким:

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'});

sequelize.sync();

Когда я запускаю этот код, консоль узла возвращает мне сообщение об ошибке:

"Необработанное отклонение SequelizeDatabaseError: Не удалось добавить ограничение внешнего ключаОтсутствует индекс для ограничения «towns_ibfk_1» в ссылочной таблице «страны».Я действительно ценю твою помощь.Спасибо.

Приведенный выше код взят из Ассоциация часть учебника (http://docs.sequelizejs.com/manual/tutorial/associations.html) Ассоциации «один ко многим».


Я также прилагаюкод, автоматически сгенерированный Sequelize:

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;

На первый взгляд кажется, что синтаксис SQL здесь неправильный, но в любом случае это приводит к ошибке. Кто-нибудь может выяснить, в чем дело? Или это проблема?Сиквелиз?

1 Ответ

0 голосов
/ 04 января 2019

Эта ошибка произошла из-за синтаксической ошибки в примере кода в учебнике по 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...