sequelize - 无法添加外键约束

时间:2017-09-05 08:53:27

标签: javascript mysql node.js express sequelize.js

我试图在两个表之间设置1:1的关系。 RefreshToken表将有两个foreignKey关联到Users表,如下图所示: enter image description here

我使用sequelize-auto来生成我的续集模型。

用户型号:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('Users', {
    idUsers: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true
    },
    name: {
      type: DataTypes.STRING(45),
      allowNull: true
    },
    mail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true
    }
  }, {
    tableName: 'Users'
  });
};

RefreshToken模型:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('RefreshToken', {
    idRefreshToken: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true
    },
    token: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    userId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'Users',
        key: 'idUsers'
      }
    },
    userEmail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'Users',
        key: 'mail'
      }
    }
  }, {
    tableName: 'RefreshToken'
  });
};

运行应用程序时,收到此错误:

  

未处理拒绝错误:SequelizeDatabaseError:   ER_CANNOT_ADD_FOREIGN:无法添加外键约束

我尝试添加显式关系,在Users表中添加:

User.associate = (models) => {
    User.hasOne(models.RefreshToken, {
      foreignKey: 'userId'
    });
    User.hasOne(models.RefreshToken, {
      foreignKey: 'userEmail'
    });
  };

并在RefreshToken中:

RefreshToken.associate = (models) => {
    RefreshToken.belongsTo(models.Users, {
      foreignKey: 'userId'
    });
    RefreshToken.belongsTo(models.Users, {
      foreignKey: 'userEmail'
    });
  };

但我再次收到同样的错误。如果我删除了RefreshToken表中的引用,我没有看到任何错误,但是当我检查数据库时,我没有看到任何与电子邮件和用户ID的外键关系约束

2 个答案:

答案 0 :(得分:7)

这是常见的类型错误,主要是由于

1。当主键数据类型和外键数据类型不匹配

return sequelize.define('RefreshToken', {
    userId: {
      type: DataTypes.INTEGER(11), // The data type defined here and 
      references: {
        model: 'Users',
        key: 'idUsers'
      }
    }, 


return sequelize.define('Users', {
    idUsers: {
      type: DataTypes.INTEGER(11),  // This data type should be the same
    },

2。当引用的键不是主键或唯一键时。

您不能有两个主键,因此其他引用的键应定义为唯一。 unique:true

 return sequelize.define('Users', {
    idUsers: {
      primaryKey: true  
    },
    mail: {
      type: DataTypes.STRING(45),
      allowNull: false,
      primaryKey: true   // You should change this to 'unique:true'. you cant hv two primary keys in one table. 
    }

答案 1 :(得分:1)

我看到两个问题:

没有表应该包含两个主键,userId不应该是整数,它应该是UUID。

我将外键设置为INT,它给了我错误:

  

未处理拒绝SequelizeDatabaseError:外键约束   “constraint_name_here”无法实现

尝试更改:

userId: {
  type: DataTypes.INTEGER(11),
  allowNull: false,
  primaryKey: true,
  references: {
    model: 'Users',
    key: 'idUsers'
  }
},

userId: {
  type: DataTypes.UUID,
  allowNull: false,
  foreignKey: true,
  references: {
    model: 'Users',
    key: 'idUsers'
  }
},