ON DELETE CASCADE for multiple foreign keys with Sequelize
ON DELETE CASCADE for multiple foreign keys with Sequelize
假设我有三个模型:
- 任务:需要完成的事情,例如"take out the recycling"。可以做很多次。
- 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 都会按预期删除。但是,当我删除任务列表时,其关联的任务列表条目只是将任务列表的外键设置为 null
.
似乎 Sequelize 正在生成以下 table:
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 而言是这样。
关于如何更正此问题的任何想法?
你能试试吗
TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);
而不是
TaskListEntry.belongsToMany(TaskList);
TaskListEntry.belongsToMany(Task);
因为,根据我对这个问题的理解,一条TaskListEntry记录只能属于一个Task和一个TaskList。
或者您是想在这里建立 Many-to-Many 关系吗?在那种情况下,我认为这不是理想的实施方式。
我必须为 foreignKey
设置 allowNull:false
才能使 '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 })
假设我有三个模型:
- 任务:需要完成的事情,例如"take out the recycling"。可以做很多次。
- 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 都会按预期删除。但是,当我删除任务列表时,其关联的任务列表条目只是将任务列表的外键设置为 null
.
似乎 Sequelize 正在生成以下 table:
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 而言是这样。
关于如何更正此问题的任何想法?
你能试试吗
TaskListEntry.belongsTo(TaskList);
TaskListEntry.belongsTo(Task);
而不是
TaskListEntry.belongsToMany(TaskList);
TaskListEntry.belongsToMany(Task);
因为,根据我对这个问题的理解,一条TaskListEntry记录只能属于一个Task和一个TaskList。
或者您是想在这里建立 Many-to-Many 关系吗?在那种情况下,我认为这不是理想的实施方式。
我必须为 foreignKey
设置 allowNull:false
才能使 '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 })