Sequelize属于不向数据库表添加外键约束

Sequelize属于不向数据库表添加外键约束

本文介绍了Sequelize属于不向数据库表添加外键约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using sequelize ORM for my node.js application and have created two simple models.

  1. company.model.js
  2. location.model.js

一家公司可以有多个地点,一个地点可以属于一个公司.

A company can have multiple locations and a location can belongs to one company.

这是我的模型:

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;
};

location.model.js

'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}) 将创建两个表并向位置表添加外键索引.但它只是创建表.位置表中没有任何名为 company_id 的列.

Now I expected that It will sequelize.sync({force:true}) will create both tables and add a foreign key index to the location table. But it is only create tables. There is no any column named company_id on location table.

推荐答案

通过在 sequelize 的单例模块中编写几行代码,我自己解决了问题:

Resolved the problem at my own by writing the few lines of code in my singleton module of sequelize:

Object.keys(db).forEach(function(modelName) {
  if(db[modelName].hasOwnProperty('associate')) {
    db[modelName].associate(db);
  }
});

代码将遍历所有模型并直接调用它们的关联方法,因为它们已被定义为 classMethods.

The code will iterate over all the models and call their associate methods directly as they have been defined as classMethods.

这篇关于Sequelize属于不向数据库表添加外键约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 01:44