如何使用 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 字段中使用毫秒?