Mysql Sequelize belong不向数据库表添加外键约束

Mysql Sequelize belong不向数据库表添加外键约束,mysql,sequelize.js,Mysql,Sequelize.js,我正在为node.js应用程序使用sequelize ORM,并创建了两个简单的模型 company.model.js location.model.js 一个公司可以有多个地点,而一个地点可以属于一个公司 以下是我的模型: company.model.js 'use strict'; module.exports = function(sequelize, DataTypes) { var Company = sequelize.define('Company', { id: {

我正在为node.js应用程序使用sequelize ORM,并创建了两个简单的模型

  • company.model.js
  • location.model.js
  • 一个公司可以有多个地点,而一个地点可以属于一个公司

    以下是我的模型:

    company.model.js

    'use strict';
    
    module.exports = function(sequelize, DataTypes) {
      var Company = sequelize.define('Company', {
        id: {
          type: DataTypes.INTEGER(3),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          comment: "Primary and auto incremented key of the table"
        },
        companyName: {
          field: "company_name",
          type: DataTypes.STRING(255),
          allowNull: false,
          comment: "Company Name"
        },
        companyCode: {
          field: "company_code",
          type: DataTypes.STRING(20),
          allowNull: false,
          unique: true,
          comment: "Company Code"
        },
        contactName: {
          field: "contact_name",
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: "Name of contact person"
        },
        contactNo: {
          field: "contact_no",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Company contact number"
        },
        fax: {
          field: "fax",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Company fax number"
        },
        website: {
          field: "website",
          type: DataTypes.STRING(50),
          allowNull: true,
          comment: "Company website url if exist for e.g. mumbai.spiderman.com",
          validate: {
            isUrl: true
          }
        },
        country: {
          field: "country_id",
          type: DataTypes.INTEGER(3),
          allowNull: false,
          comment: "Country for address purpose"
        },
        state: {
          field: "state_id",
          type: DataTypes.INTEGER(4),
          allowNull: true,
          comment: "State for address purpose"
        },
        city: {
          field: "city_id",
          type: DataTypes.INTEGER(5),
          allowNull: true,
          comment: "City for address purpose"
        },
        landmark: {
          field: "landmark",
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: "Address landmark"
        },
        address: {
          field: "address",
          type: DataTypes.TEXT,
          allowNull: true,
          comment: "Company address"
        },
        status: {
          field: "status",
          type: DataTypes.ENUM('ACTIVE','INACTIVE','DELETED'),
          allowNull: false,
          defaultValue: 'ACTIVE',
          comment: "Wether a company is active, inactive or deleted"
        }
      },{
    
        underscored: true,
        freezeTableName:true,
        tableName:'company',
        classMethods:{
          associate:function(models){
            Company.hasMany(models.Location);
          }
        },
    
      });
    
      return Company;
    };
    
    'use strict';
    
    module.exports = function(sequelize, DataTypes) {
      var Location = sequelize.define('Location', {
        id: {
          type: DataTypes.INTEGER(5),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          comment: "Primary and auto incremented key of the table"
        },
        locationType: {
          field: "location_type",
          type: DataTypes.ENUM('HEAD_OFFICE','REGIONAL_OFFICE','FRANCHISE'),
          allowNull: false,
          comment: "Type of location"
        },
        locationName: {
          field: "location_name",
          type: DataTypes.STRING(200),
          allowNull: false,
          comment: "Name of location"
        },
        locationCode: {
          field: "location_code",
          type: DataTypes.STRING(20),
          allowNull: false,
          unique: true,
          comment: "Location Code"
        },
        contactName: {
          field: "contact_name",
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: "Name of contact person"
        },
        contactNo: {
          field: "contact_no",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Location contact number"
        },
        fax: {
          field: "fax",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Location fax number"
        },
        website: {
          field: "website",
          type: DataTypes.STRING(50),
          allowNull: true,
          comment: "Location specific website url if exist for e.g. mumbai.spiderman.com",
          validate: {
            isUrl: true
          }
        },
        country: {
          field: "country_id",
          type: DataTypes.INTEGER(3),
          allowNull: false,
          comment: "Location country for address purpose"
        },
        state: {
          field: "state_id",
          type: DataTypes.INTEGER(4),
          allowNull: true,
          comment: "Location state for address purpose"
        },
        city: {
          field: "city_id",
          type: DataTypes.INTEGER(5),
          allowNull: true,
          comment: "Location city for address purpose"
        },
        landmark: {
          field: "landmark",
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: "Location landmark"
        },
        address: {
          field: "address",
          type: DataTypes.TEXT,
          allowNull: true,
          comment: "Location address"
        },
        status: {
          field: "status",
          type: DataTypes.ENUM('ACTIVE','INACTIVE','DELETED'),
          allowNull: false,
          defaultValue: 'ACTIVE',
          comment: "Weather a location is active, inactive or deleted"
        },
        createdBy: {
          field: "created_by",
          type: DataTypes.INTEGER(11),
          allowNull: true,
          comment: "User ID who created this location"
        },
        updatedBy: {
          field: "updated_by",
          type: DataTypes.INTEGER(11),
          allowNull: true,
          comment: "User ID who updated this location"
        }
      },
      {
        timestamps: true,
        underscored: true,
        freezeTableName:true,
        tableName:'location',
        defaultScope: {
          where: {
            status: 'ACTIVE'
          }
        },
        classMethods:{
          associate:function(models){
            Location.belongsTo(models.Company, { foreignKey:'company_id', foreignKeyConstraint:true} );
          }
        }
      });
    
      return Location;
    };
    
    location.model.js

    'use strict';
    
    module.exports = function(sequelize, DataTypes) {
      var Company = sequelize.define('Company', {
        id: {
          type: DataTypes.INTEGER(3),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          comment: "Primary and auto incremented key of the table"
        },
        companyName: {
          field: "company_name",
          type: DataTypes.STRING(255),
          allowNull: false,
          comment: "Company Name"
        },
        companyCode: {
          field: "company_code",
          type: DataTypes.STRING(20),
          allowNull: false,
          unique: true,
          comment: "Company Code"
        },
        contactName: {
          field: "contact_name",
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: "Name of contact person"
        },
        contactNo: {
          field: "contact_no",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Company contact number"
        },
        fax: {
          field: "fax",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Company fax number"
        },
        website: {
          field: "website",
          type: DataTypes.STRING(50),
          allowNull: true,
          comment: "Company website url if exist for e.g. mumbai.spiderman.com",
          validate: {
            isUrl: true
          }
        },
        country: {
          field: "country_id",
          type: DataTypes.INTEGER(3),
          allowNull: false,
          comment: "Country for address purpose"
        },
        state: {
          field: "state_id",
          type: DataTypes.INTEGER(4),
          allowNull: true,
          comment: "State for address purpose"
        },
        city: {
          field: "city_id",
          type: DataTypes.INTEGER(5),
          allowNull: true,
          comment: "City for address purpose"
        },
        landmark: {
          field: "landmark",
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: "Address landmark"
        },
        address: {
          field: "address",
          type: DataTypes.TEXT,
          allowNull: true,
          comment: "Company address"
        },
        status: {
          field: "status",
          type: DataTypes.ENUM('ACTIVE','INACTIVE','DELETED'),
          allowNull: false,
          defaultValue: 'ACTIVE',
          comment: "Wether a company is active, inactive or deleted"
        }
      },{
    
        underscored: true,
        freezeTableName:true,
        tableName:'company',
        classMethods:{
          associate:function(models){
            Company.hasMany(models.Location);
          }
        },
    
      });
    
      return Company;
    };
    
    'use strict';
    
    module.exports = function(sequelize, DataTypes) {
      var Location = sequelize.define('Location', {
        id: {
          type: DataTypes.INTEGER(5),
          allowNull: false,
          primaryKey: true,
          autoIncrement: true,
          comment: "Primary and auto incremented key of the table"
        },
        locationType: {
          field: "location_type",
          type: DataTypes.ENUM('HEAD_OFFICE','REGIONAL_OFFICE','FRANCHISE'),
          allowNull: false,
          comment: "Type of location"
        },
        locationName: {
          field: "location_name",
          type: DataTypes.STRING(200),
          allowNull: false,
          comment: "Name of location"
        },
        locationCode: {
          field: "location_code",
          type: DataTypes.STRING(20),
          allowNull: false,
          unique: true,
          comment: "Location Code"
        },
        contactName: {
          field: "contact_name",
          type: DataTypes.STRING(100),
          allowNull: true,
          comment: "Name of contact person"
        },
        contactNo: {
          field: "contact_no",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Location contact number"
        },
        fax: {
          field: "fax",
          type: DataTypes.STRING(20),
          allowNull: true,
          comment: "Location fax number"
        },
        website: {
          field: "website",
          type: DataTypes.STRING(50),
          allowNull: true,
          comment: "Location specific website url if exist for e.g. mumbai.spiderman.com",
          validate: {
            isUrl: true
          }
        },
        country: {
          field: "country_id",
          type: DataTypes.INTEGER(3),
          allowNull: false,
          comment: "Location country for address purpose"
        },
        state: {
          field: "state_id",
          type: DataTypes.INTEGER(4),
          allowNull: true,
          comment: "Location state for address purpose"
        },
        city: {
          field: "city_id",
          type: DataTypes.INTEGER(5),
          allowNull: true,
          comment: "Location city for address purpose"
        },
        landmark: {
          field: "landmark",
          type: DataTypes.STRING(255),
          allowNull: true,
          comment: "Location landmark"
        },
        address: {
          field: "address",
          type: DataTypes.TEXT,
          allowNull: true,
          comment: "Location address"
        },
        status: {
          field: "status",
          type: DataTypes.ENUM('ACTIVE','INACTIVE','DELETED'),
          allowNull: false,
          defaultValue: 'ACTIVE',
          comment: "Weather a location is active, inactive or deleted"
        },
        createdBy: {
          field: "created_by",
          type: DataTypes.INTEGER(11),
          allowNull: true,
          comment: "User ID who created this location"
        },
        updatedBy: {
          field: "updated_by",
          type: DataTypes.INTEGER(11),
          allowNull: true,
          comment: "User ID who updated this location"
        }
      },
      {
        timestamps: true,
        underscored: true,
        freezeTableName:true,
        tableName:'location',
        defaultScope: {
          where: {
            status: 'ACTIVE'
          }
        },
        classMethods:{
          associate:function(models){
            Location.belongsTo(models.Company, { foreignKey:'company_id', foreignKeyConstraint:true} );
          }
        }
      });
    
      return Location;
    };
    

    现在我希望它将
    sequelize.sync({force:true})
    将创建这两个表并向location表添加外键索引。但它只是创建表。位置表中没有任何名为
    company\u id
    的列。

    通过在sequelize的singleton模块中编写几行代码,自行解决了此问题:

    Object.keys(db).forEach(function(modelName) {
      if(db[modelName].hasOwnProperty('associate')) {
        db[modelName].associate(db);
      }
    });
    
    代码将遍历所有模型,并直接调用它们的关联方法,因为它们被定义为类方法