【问题标题】:ON DELETE CASCADE for multiple foreign keys with SequelizeON DELETE CASCADE 用于 Sequelize 的多个外键
【发布时间】:2019-10-06 09:36:14
【问题描述】:

假设我有三个模型:

  • 任务:需要完成的事情,例如“取出回收”。可以多次进行。
  • TaskList:一个表示任务列表的对象,并拥有自己的元数据。
  • TaskListEntry: Task 和 TaskList 之间的关联,可能包含优先级或分配给它的人员等数据。

我的关联设置如下:

Task.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true}));

TaskList.hasMany(TaskListEntry, {onDelete: 'cascade', hooks: true});

TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);

这工作正常,除了删除。当我删除任务时,任何关联的 TaskListEntries 都会按预期删除。但是,当我删除一个 TaskList 时,其关联的 TaskListEntries 只是将 TaskList 的外键设置为 null

Sequelize 似乎正在生成下表:

CREATE TABLE `TaskListEntries`(
  `id` UUID PRIMARY KEY, 
  /* some other fields here */
  `createdAt` DATETIME NOT NULL, 
  `updatedAt` DATETIME NOT NULL, 
  `TaskId` UUID REFERENCES `Tasks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
  `TaskListId` UUID REFERENCES `TaskLists`(`id`) ON DELETE SET NULL ON UPDATE CASCADE);

尽管关联配置相同,但任务和任务列表的外键具有不同的DELETE 行为。如果我删除其中一个关联,其他关联就可以正常工作。

因此,我认为问题在于ON DELETE CASCADE 的多个外键,至少在 Sequelize 看来是这样。

关于如何纠正这个问题的任何想法?

【问题讨论】:

  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&可运行代码;具有期望和实际输出的示例输入(包括逐字错误消息);明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)

标签: sql sqlite foreign-keys sequelize.js cascade


【解决方案1】:

你可以试试

TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);

而不是

TaskListEntry.belongsToMany(TaskList);
TaskListEntry.belongsToMany(Task); 

因为,根据我对这个问题的理解,单个TaskListEntry记录只能属于单个Task和单个TaskList。

或者你想在这里建立一个多对多的关系?在那种情况下,我认为这不是理想的实现方式。

【讨论】:

  • 啊,谢谢!非常抱歉...我 am 两者都使用.belongsTo。我不小心在我的问题中发布了一些实验,而不是真实的代码。对此感到抱歉,感谢您的回复纠正我。我已经更正了我的问题中的代码。是的,一个TaskListEntry 只与一个Task 和一个TaskList 相关联。一个 Task 可以有多个与之关联的 TaskListEntries,TaskList 也可以。
  • 如果我错了,请纠正我。你需要belongsTo 和hasMany 关系吗?理想情况下,您可以删除最后两行的 belongsTo 关联。我觉得值得一试。
【解决方案2】:

我必须将allowNull:false 设置为foreignKey 才能使删除时的“CASCADE”起作用。所以在你的情况下应该是这样的:

TaskListEntry.belongsTo(TaskList, {
  onDelete: 'cascade', 
  foreignKey: { allowNull: false }    //   <-------------
  hooks: true
});

鉴于这种情况,您的模型通常类似于 http://docs.sequelizejs.com/manual/associations.html#belongs-to-many-associations 中的这种结构:

class User extends Model {}
User.init({}, { sequelize, modelName: 'user' })

class Project extends Model {}
Project.init({}, { sequelize, modelName: 'project' })

class UserProjects extends Model {}
UserProjects.init({
  status: DataTypes.STRING
}, { sequelize, modelName: 'userProjects' })

User.belongsToMany(Project, { through: UserProjects })
Project.belongsToMany(User, { through: UserProjects })

【讨论】:

  • 谢谢,“通过”示例正是我所需要的。我没有意识到我能够在那里添加其他属性,并直接查询。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2021-03-29
  • 1970-01-01
相关资源
最近更新 更多