【问题标题】:How to choose name of Foreign Key column using Sequelize and mySql?如何使用 Sequelize 和 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')?

【问题讨论】:

    标签: mysql node.js orm sequelize.js


    【解决方案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 但我设法解决了它。查看我自己的回复,了解我是如何做到的。
        猜你喜欢
        • 1970-01-01
        • 2019-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多