带Sequelize的多个外键的ON DELETE CASCADE

Bra*_*rad 5 sql sqlite cascade foreign-keys sequelize.js

假设我有三个模型:

  • 任务:需要完成的事情,例如“回收”。可以做很多次。
  • TaskList:代表任务列表的对象,并且具有自己的元数据。
  • TaskListEntry: Task和TaskList之间的关联,可能具有诸如优先级或分配给谁的数据。

我的关联设置如下:

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

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

TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);
Run Code Online (Sandbox Code Playgroud)

除删除外,此方法工作正常。当我删除任务时,所有关联的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);
Run Code Online (Sandbox Code Playgroud)

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

因此,我认为问题是使用多个外键ON DELETE CASCADE,至少就Sequelize而言是如此。

关于如何纠正这个问题有什么想法吗?

Sve*_*415 6

我必须设置allowNull:falseforeignKey为获得“CASCADE”上删除工作。所以在你的情况下应该是这样的:

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

鉴于这种情况,您的模型通常类似于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 })
Run Code Online (Sandbox Code Playgroud)