不创建带有 Sequelize 的外键

Posted

技术标签:

【中文标题】不创建带有 Sequelize 的外键【英文标题】:Foreign keys with Sequelize are not created 【发布时间】:2014-08-10 04:27:42 【问题描述】:

我将 Sequelize 用于我的服务器(使用 mysql 方言);在 Sequelize 的文档中是这样写的:

var Task = this.sequelize.define('Task',  title: Sequelize.STRING )
, User = this.sequelize.define('User',  username: Sequelize.STRING )

User.hasMany(Task)
Task.belongsTo(User)

自动创建带有约束的外键引用; 但对我来说这不会发生:

var Shop = sequelize.define('Shop', 
    name: Sequelize.STRING,
    address: Sequelize.STRING,
    phone: Sequelize.STRING,
    email: Sequelize.STRING,
    percentage: Sequelize.FLOAT,
    text: Sequelize.TEXT,
    categories: Sequelize.TEXT,
    start: Sequelize.DATE,
    end: Sequelize.DATE
);

var Offer = sequelize.define('Offer', 
    name: Sequelize.STRING,
    deadline: Sequelize.DATE,
    optionDuration: Sequelize.INTEGER
);

Shop.hasMany(Offer);
Offer.belongsTo(Shop);

这会创建两个表 shop 和 offer,它们都只有“id”主键

我也有一些 n:m 关联,例如:

Group.hasMany(Accesslevel);
Accesslevel.hasMany(Group);

但同样在这种情况下,在 Sequelize 创建的连接表中,没有外键; 所以如果我删除前。访问级别,而不是连接表访问级别组中的相应记录不会被删除。

有人知道我做错了什么还是遗漏了什么? 我需要的是为关联创建所有外键以及指定行为“onDelete”和“onUpdate”(级联)的可能性

-- 更新 我已经创建了一个执行同步的路由:

myServer.get('/sync', function (req, res) 
    sequelize.sync(force: true).success(function() 
        console.log('sync done');
        res.send(200, 'sync done');
    ).error(function(error) 
        console.log('there was a problem');
        res.send(200, 'there was a problem');
    );
);

然后在浏览器中输入 127.0.0.1:port/sync 来创建数据库结构

【问题讨论】:

sequelize 不支持外键,需要自己创建。 @mpm 完全不正确,sequelizejs.com/docs/1.7.8/associations#foreign-keys @WillemD'haeseleer 好吧,当我使用它时就是这种情况,很高兴现在支持它。 是的,我只是在链接同一个文档页面...但是您知道为什么在我的情况下,外键没有按照文档中的说明自动创建吗? 创建表后添加关系了吗?你打电话给sync了吗,你需要force: true来更新表格(将删除表格)。你在使用 InnoDB 吗? 【参考方案1】:

您是否在创建表(在数据库中)后添加了关系? 如果你修改你的方案并再次运行你的程序,你需要.sync( force: true )。 如果数据库中尚不存在该表,Sequelize 只会创建该表及其所有引用。

你是在所有关联都建立后调用同步吗?

你在使用 InnoDB 吗?

奇怪的是我可以重现,最简单的解决方法是手动定义密钥我认为这就是我解决它的方法,否则我不确定可能是一个错误。

请看这里: http://sequelizejs.com/docs/latest/associations#block-3-line-24

【讨论】:

我在模型之后定义了所有关联,如第一篇文章中所述;然后我在执行同步(force:true)的服务器中创建了一个路由/sync,以及另一个自动插入一些记录的路由/dummy-data;所以我运行 /sync 然后 /dummy-data... 我使用 InnoDB ... @CerealKiller 你用的是什么版本,好像这可能是< 1.7.6 github.com/sequelize/sequelize/pull/1818的问题 我正在使用最新的 Sequelize 2.0.0-dev9 - 谢谢你,我也会关注这个问题 好的,最后问题是由于关于 n:m 关联的问题;在其他情况下 (1:n) 有效【参考方案2】:

你应该给这样的外键,它与同步无关。

Offer.associate = function (models) 
    models. Offer.belongsTo(models. Offer, 
        onDelete: "CASCADE",
        foreignKey: 'shopId',
        targetKey: 'id'
    );
;

【讨论】:

【参考方案3】:

这个问题居然回答here

由于琐碎的答案被转换为 cmets,并且很难在问题中注意到它们,因此我将在此处重复其要点。

要向列添加引用约束,您可以将选项 onUpdate 和 onDelete 传递给关联调用。 . . .

User.hasMany(Task, onDelete: 'SET NULL', onUpdate: 'CASCADE' )

【讨论】:

以上是关于不创建带有 Sequelize 的外键的主要内容,如果未能解决你的问题,请参考以下文章

尝试将行插入表因为带有sequelize.js的UUID外键时出错

Laravel Eloquent 关系与多个带有“OR”的外键

Nodejs sequelize 如何截断外键引用的表

Sequelize ORM中HasOne和BelongsTo的区别

无法设置IdentityUser上的外键

由于带有 sequelize.js 的 UUID 外键,尝试将行插入表时出错