带Sequelize的多个外键的ON DELETE CASCADE

时间:2019-05-20 02:47:54

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

假设我有三个模型:

  • 任务:需要完成的事情,例如“回收”。可以做很多次。
  • 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);

尽管关联配置相同,但Task和TaskList的外键具有不同的DELETE行为。如果我删除其中一个关联,则其他关联就可以了。

因此,我认为问题是ON DELETE CASCADE带有多个外键,至少在Sequelize看来如此。

关于如何更正此问题的任何想法?

2 个答案:

答案 0 :(得分:3)

您可以尝试

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

代替

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

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

还是您要在这里建立多对多关系?在那种情况下,我认为这不是理想的实现方式。

答案 1 :(得分:1)

我必须将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 })