【问题标题】:SequelizeForeignKeyConstraintError: update or delete on table X violates foreign key constraint fkey on table YSequelizeForeignKeyConstraintError:表 X 上的更新或删除违反了表 Y 上的外键约束 fkey
【发布时间】:2021-09-14 22:34:03
【问题描述】:

我在更新用户表中的显示名称时遇到问题,出现以下错误。

关系

用户也可以是主管。并且两个表都有一个名称字段(用户上的显示名称和主管上的名称)。如果用户 X 编辑他的个人资料并更改显示名称,我希望更改反映在主管表名称字段中。我虽然级联可以工作,但我没有得到它。

(node:25136) UnhandledPromiseRejectionWarning: SequelizeForeignKeyConstraintError: update or delete on table "c_user" violates foreign key constraint "c_supervisor_name_fkey" on table "c_supervisor"

user表和supervisor表是1:n的关系。

用户模型

  const User = sequelize.define('user', {
    id: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    displayName: {
      type: Sequelize.STRING,
      allowNull: false,
      unique: true
    },

  User.associate = function(models) {
    User.hasOne(models.supervisor, { foreignKey: "userId" });
  };
    User.hasOne(models.supervisor, { foreignKey: "name" });
    
 return User;
};

主管模式

module.exports = (sequelize, Sequelize) => {
  const Supervisor = sequelize.define('supervisor', {
    id: {
       type: Sequelize.INTEGER,
       allowNull: false,
       primaryKey: true,
       autoIncrement: true
     },
    userId: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      allowNull: false,
      unique: true,
      references: {
        model: 'c_user',
        key: 'id'
      }
    },
    name: {
      type: Sequelize.STRING,
      allowNull: false,
      references: {
        model: 'c_user',
        key: 'displayName'
      }
    },

Supervisor.associate = function(models) {
    Supervisor.belongsTo(models.user, {
      foreignKey: "userId", targetKey: "id", onDelete: "CASCADE", onUpdate: "CASCADE"
    });
    Supervisor.belongsTo(models.user, {
      foreignKey: "name", targetKey: "displayName", onDelete: "CASCADE", onUpdate: "CASCADE"
    });
  }
  
  return Supervisor;
};

如果我更新用户表中的显示名称,我希望它级联到主管中的名称并更新它,但我得到了上面的错误。

【问题讨论】:

  • 为什么名称与关系相关?
  • @Andreas 用户有一个个人资料页面,他们可以在其中编辑他们的 displayName。然后同一个用户在主管模型中有一个名称字段。因此,我们希望如果用户在用户模型中编辑名称,则更改应立即反映在主管模型中。
  • 这不能回答我的问题。为什么名称存储在两个地方?为什么在关系中使用它?关系是用 id 建立的。就是这样。
  • @Andreas 在主管控制器中,我使用 userId 来获取用户 displayName 并将其用作名称。在前端填写主管表单时,用户只需要指定userId。没有名称输入,它在后端处理。即使我删除了名称关系并仅使用 userId 来获取 displayName,当我尝试更新用户 displayName 时仍然会收到上述错误。

标签: javascript database postgresql sequelize.js


【解决方案1】:

首先使用名称作为外键是个坏主意。其次,如果您将两个相同的表相互关联,则需要使用别名来区分它们的关联方式。例如:

// user-to-supervisor one to one relation as user
User.hasOne(Supervisor, {foreignKey: 'userId', as: 'user'})
Supervisor.belongsTo(User)
// user-to-supervisor one to one relation as username
User.hasOne(Supervisor, {foreignKey: 'name', as: 'username'})
Supervisor.belongsTo(User)

希望它会有所帮助,但是您尝试做的事情是不切实际的。 你能更具体地谈谈你试图建立的关系吗?

【讨论】:

  • 用户也可以是主管。并且两个表都有一个名称字段(用户上的显示名称和主管上的名称)。如果用户 X 编辑他的个人资料并更改显示名称,我希望更改反映在主管表名称字段中。我虽然级联可以工作,但我没有得到它。
  • @Wacademy 您只能构建一个用户模型并添加一个名为角色的新字段,其中可以接受用户、主管。
  • 我的用户模型已经有角色,但主管是一个单独的模型而不是角色。谢谢
猜你喜欢
  • 2021-08-04
  • 1970-01-01
  • 2017-11-24
  • 2019-03-05
  • 1970-01-01
  • 2019-11-05
  • 2018-05-17
  • 2017-11-18
  • 1970-01-01
相关资源
最近更新 更多