Sequelize.js 外键

Posted

技术标签:

【中文标题】Sequelize.js 外键【英文标题】:Sequelize.js foreign key 【发布时间】:2012-12-19 15:07:28 【问题描述】:

使用 Sequelize.js 时,以下代码不会在表上添加任何外键。

var MainDashboard = sequelize.define('main_dashboard', 
  title: Sequelize.STRING
, 
  freezeTableName: true
)

MainClient.hasOne(MainDashboard,  foreignKey: 'idClient' )
MainDashboard.hasOne(MainClient,  foreignKey: 'clientId' )

sequelize.sync( force: true )

有没有办法强制 Sequelize.js 添加这些外键约束?

【问题讨论】:

难道没有一个叫ForeignKey:true的属性可以在sequelize.define()函数中为一个列设置吗? 【参考方案1】:

在我遇到同样的问题之前,当我了解设置 Sequelize 的功能时解决了。

直截了当!

假设我们有两个对象:PersonFather

var Person = sequelize.define('Person', 

        name: Sequelize.STRING
);

var Father = sequelize.define('Father', 

        age: Sequelize.STRING,
        //The magic start here
        personId: 
              type: Sequelize.INTEGER,
              references: 'persons', // <<< Note, its table's name, not object name
              referencesKey: 'id' // <<< Note, its a column name
        
);

Person.hasMany(Father); // Set one to many relationship

也许对你有帮助

编辑:

您可以阅读此内容以更好地理解:

http://docs.sequelizejs.com/manual/tutorial/associations.html#foreign-keys

【讨论】:

现在不推荐使用referencesreferencesKey => Utils deprecated Non-object references property found. Support for that will be removed in version 4. Expected references: model: "value", key: "key" instead of references: "value", referencesKey: "key" . 这不是一个很好的例子,最后一个命令说one Person has many Fathers 这听起来不自然【参考方案2】:

对于 Sequelize 4,这已更新为以下内容:


const Father = sequelize.define('Father', 
        name: Sequelize.STRING
);

const Child = sequelize.define('Child', 
    age: Sequelize.STRING,
    fatherId: 
       type: Sequelize.INTEGER,
       references: 
          model: 'fathers', // 'fathers' refers to table name
          key: 'id', // 'id' refers to column name in fathers table
       
    
);

Father.hasMany(Child); // Set one to many relationship

编辑: 你可以在https://sequelize.org/master/manual/assocs.html阅读更多关于关联的信息

【讨论】:

【参考方案3】:

您需要添加foreignKeyConstraint: true

试试:

MainClient.hasOne(MainDashboard,  foreignKey: 'idClient', foreignKeyConstraint: true )

【讨论】:

这仍然是一个选项吗?我在the API 中没有看到属性foreignKeyConstraint;只有foreignKey。哦!也许该属性现在被简单地称为:constraints?它被描述为:“应该在外键上启用更新和删除约束。”【参考方案4】:

我刚刚尝试运行您的代码,并且行似乎创建得很好:

CREATE TABLE IF NOT EXISTS `main_dashboard` (`title` VARCHAR(255), `id` INTEGER NOT NULL auto_increment , `idClient` INTEGER, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `main_client` (`id` INTEGER NOT NULL auto_increment,  `clientId` INTEGER, PRIMARY KEY (`id`)) ENGINE=InnoDB;

clientId添加到main_clientidClient添加到main_dashboard

您似乎对hasOne 方法的作用有些困惑。每次调用hasOne 时都会创建一个关联,因此您的代码有效地将两个表关联了两次。你要找的方法是belongsTo

如果您希望每个客户都有一个仪表板,代码如下:

MainClient.hasOne(MainDashboard,  foreignKey: 'clientId' )
MainDashboard.belongsTo(MainClient,  foreignKey: 'clientId' )

这会在main_dashboard 表上创建一个clientId 字段,该字段与main_client 表的id 字段相关

简而言之,belongsTo 将关系添加到您正在调用该方法的表中,hasOne 将其添加到作为参数给出的表中。

【讨论】:

【参考方案5】:

这非常简单。

const MainDashboard = this.sequelize.define('main_dashboard', /* attributes */),
      MainClient    = this.sequelize.define('main_client', /* attributes */);

MainDashboard.belongsTo(MainClient,  foreignKey: 'clientId' ); // Adds clientId to MainDashboard

它将作为外键链接,您可以将其用作关联。如果我遗漏了什么,请告诉我。

【讨论】:

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

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

如何安装 sequelize.js 二进制文件?

获取由 sequelize.js 生成的原始查询 [重复]

sequelize.js - 你需要手动安装 mysql 包

在 Sequelize.js 中为多对多关系添加默认角色

sequelize.js TIMESTAMP 不是 DATETIME