如何使用 Sequelize 和 mySql 选择外键列的名称?

Posted

技术标签:

【中文标题】如何使用 Sequelize 和 mySql 选择外键列的名称?【英文标题】:How to choose name of Foreign Key column using Sequelize and mySql? 【发布时间】:2015-03-19 07:44:44 【问题描述】:

我正在使用 sequelize 在我的节点应用程序中为 mysql 数据库模式建模。我的模型的摘录如下所示: 我有一个公司表和一个部门表。一个公司可以有多个部门,一个部门只属于一个公司。我将其建模如下:

公司表:

module.exports = function(sequelize, DataTypes)
return Company = sequelize.define('Company', 
    companyId: 
        type: DataTypes.INTEGER,
        primaryKey: true,
        allowNull: false,
        autoIncrement: true,
        unique: true            
    ,
    name: 
        type: DataTypes.STRING,
        allowNull: false
    
)

部门表:

var Company = require('./company');

module.exports = function(sequelize,DataTypes) 
return Department = sequelize.define('Department', 
    departmentId: 
        type: DataTypes.INTEGER,
        primaryKey: true,
        allowNull: false,
        autoIncrement: true,
        unique: true
    ,
    name: 
        type: DataTypes.STRING,
        allowNull: false            
    ,
    companyId: 
        type:           DataTypes.INTEGER,
        references:     'Companies',
        referencesKey:  'companyId',
        onDelete:       'cascade'
    
);

要将这个架构实际存储在数据库中,我使用以下代码:

var db = require('../models/index');
db["Company"].hasMany(db["Department"], as: 'departments');
db["Department"].belongsTo(db["Company"], foreignKey: 'companyId', foreignKeyConstraint: true);

models.sequelize.sync().complete(function(err)
    //irrelevant for the problem
);

问题是这段代码在部门表中创建了 2 个外键。一个在“companyId”字段上(如预期的那样),还有一个在“CompanyCompanyId”字段上,这是一个自动生成的字段。

如何确保只使用和创建我定义的外键 ('companyId')?

【问题讨论】:

【参考方案1】:

我设法解决了这个问题:

不要只在belongsTo语句中使用“foreignKey”选项,还应该在“hasMany”语句中使用它。

原始问题中发布的两个模型保持不变。我唯一需要更改的是 foreignKey 选项的位置:

var db = require('../models/index');
db["Company"].hasMany(db["Department"], as: 'departments');
db["Department"].belongsTo(db["Company"], foreignKey: 'companyId', foreignKeyConstraint: true);

改为:

var db = require('../models/index');
db["Company"].hasMany(db["Department"],  foreignKey: 'companyId');
db["Department"].belongsTo(db["Company"], foreignKey: 'companyId');

【讨论】:

是的,关系双方相同的foreignKey值解决了问题,谢谢! 如果您对foreignKey 有其他选项(例如allowNull: false),那么您可以使用name 指定其名称:foreignKey: name: 'companyId', allowNull: false 嗨,西蒙正在努力创建外键,您能帮帮我吗?【参考方案2】:

在4.4.0版本中,belongsTo函数有一个targetKey选项。

const User = this.sequelize.define('user', /* attributes */)
const Company  = this.sequelize.define('company', /* attributes */);

User.belongsTo(Company, foreignKey: 'fk_companyname', targetKey: 'name'); // Adds fk_companyname to User

更多关于http://docs.sequelizejs.com/manual/tutorial/associations.html#target-keys的信息

【讨论】:

【参考方案3】:

我知道这个线程有点老了,但我在声明 1:n 关联时遇到问题时偶然发现了它。我正在使用续集 5.21.5。引用属性中键的方式从(借用您的示例):

companyId: 
  type:           DataTypes.INTEGER,
  references:     'Companies',
  referencesKey:  'companyId'

到:

companyId: 
  type: DataTypes.INTEGER,
  references: 
    model: 'Company',
    key: 'companyId'
  

希望这对一路上疲惫的旅行者有所帮助!

【讨论】:

【参考方案4】:

Sequelize 为您创建 foreignKey 字段。因此,如果您使用的是belongsTo,则无需在Department 模型中定义字段companyId

在当前场景中,它将创建两个外键,一个在模型中定义,另一个通过belongsTo 创建,当它再次尝试创建外键时,它发现该字段已经存在,因此它创建另一个字段。

【讨论】:

感谢您的评论。我注意到 sequelize 为我创建了一个 foreignKey 字段。它被称为“CompanyCompanyId”,但我希望能够给它一个我定义的名称(即“companyId”而不是“CompanyCompanyId”)。你知道我怎样才能做到这一点吗? 您可以在选项中使用as 指定它。前任。 db["Department"].belongsTo(db["Company"], as: 'companyId', foreignKey: 'companyId', foreignKeyConstraint: true); 感谢您的意见 Nilesh 但我设法解决了它。查看我自己的回复,了解我是如何做到的。

以上是关于如何使用 Sequelize 和 mySql 选择外键列的名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Sequelize 中使用 MySQL JSON 数据类型

如何在 mysql Sequelize 实例中拥有数组的数据类型?

如何在 MySql 中使用 sequelize 运行多个原始查询?

如何在 sequelize 标准 createdAt 字段中使用毫秒?

如何使用 Sequelize.JS 选择具有 2 个唯一列的所有行?

如何使用 Multi-AZ 将 Node Sequelize 连接到 Amazon RDS MySQL