(added sql)sequelize与选项有许多关联

vof42yt1  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(292)

我是新的续集,我学习与官方教程网站(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:未能添加外键约束。引用表“countries”中缺少约束“cities\u ibfk\u 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语法似乎没有错,但无论如何,这会导致错误。有人能找出什么地方不对劲吗?或者这是一个后遗症的问题?

8tntrjer

8tntrjer1#

发生此错误是因为sequelize教程中的示例代码有语法错误。
如果我们要为外键建立规则,它必须引用被引用表的主键。问题是在代码中,外键 countryCode 试图引用 isoCodeCountry 型号(即 countries 表(以实数表示)。

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代码将转换成如下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;

要修正这个语法错误,我们必须 isoCodeCity 为主键建模。让我们修复代码:

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

当我们修复了模型定义时,代码将如我们所期望的那样正常工作!
但我想知道的是。。。官方教程怎么能发布这段代码,让初学者在不知道这行不通的情况下直接试用呢。当然,有人会说这不是续写的问题,而是理解sql的问题。但我仍然认为教程应该被修正以避免这种情况的发生。
此解决方案的局限性在于,使用此选项没有意义 sourceKey 以及 targetKey ,因为即使没有它们,sequelize也会自动找出关系并识别表中的源键和目标键。
我还是不明白。。。我想现在,我只需要不使用sourcekey和targetkey选项。

相关问题