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

问题描述:

我正在使用sequelize在我的节点应用程序中为mySql数据库模式建模。我的模型摘录如下所示: 我有一个公司表和一个部门表。一个公司可以有多个部门,一个部门只能属于一个公司。我仿照这个如下:如何使用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')被使用和创建?

我设法解决这个问题:

而是仅使用在属于关联语句的“外键” - 选项中,也应该在“的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'}); 
+0

是的,关系两边的相同foreignKey值解决了这个问题,谢谢! – Xdg 2016-10-24 07:18:24

+1

如果您有'foreignKey'的附加选项(例如'allowNull:false'),那么您可以使用'name'指定它的名称:'foreignKey:{name:'companyId',allowNull:false}'。 – 2016-12-15 10:51:10

+0

嗨西蒙正在努力创造外键你能帮助我吗? – Kannan 2017-09-26 10:57:22

Sequelize会为您创建ForeignKey字段。因此,如果您使用belongsTo,则无需在Department型号中定义字段companyId

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

+0

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 

更多信息,谢谢您的评论。我注意到sequelize为我创建了一个foreignKey字段。它被称为“CompanyCompanyId”,但我希望能够给它一个我定义的名称(即“companyId”而不是“CompanyCompanyId”)。你知道我能做到吗? – Simon 2015-01-21 08:40:50

+1

你可以在选项中使用'as'来指定它。防爆。 'db [“Department”]。belongsTo(db [“Company”],{as:'companyId',foreignKey:'companyId',foreignKeyConstraint:true});' – 2015-01-21 09:10:16

+0

感谢您输入Nilesh,但我设法修复它。检查我自己的回复,知道我是如何做到的。 – Simon 2015-01-21 13:05:26

在版本4.4.0,没有为属于关联功能的targetKey选项。在http://docs.sequelizejs.com/manual/tutorial/associations.html#target-keys