Prisma自引用一对多关系下,如何删除包含子目录的Directory?
Prisma删除包含子目录的Directory模型时触发关系约束错误的解决方法
问题背景
使用以下Prisma Schema定义目录结构,支持根目录(parentDirectoryId = null)和多级子目录:
model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("parentDirectoryId", fields: [parentDirectoryId], references: [id], onDelete: NoAction, onUpdate: NoAction) user User @relation(fields: [userId], references: [id], onDelete: Cascade) quizess Quiz[] subDirectory Directory[] @relation("parentDirectoryId") @@index([parentDirectoryId]) @@index([userId]) }
调用prisma.directory.delete()删除包含子目录的目录时,触发如下错误:
Invalid prisma.directory.delete() invocation: The change you are trying to make would violate the required relation 'parentDirectoryId' between the Directory and Directory models.
问题原因
你当前的Schema中,parentDirectory关系的onDelete被设置为NoAction,这意味着数据库会阻止删除存在子目录的父目录——因为子目录的parentDirectoryId仍指向待删除的父目录ID,违反了外键约束。
解决方案
根据业务需求选择以下两种修改方式之一,更新Schema后执行数据库迁移:
1. 删除父目录时级联删除所有子目录
将parentDirectory关系的onDelete改为Cascade,这样删除父目录时,数据库会自动删除所有关联的子目录:
model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("parentDirectoryId", fields: [parentDirectoryId], references: [id], onDelete: Cascade, onUpdate: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) quizess Quiz[] subDirectory Directory[] @relation("parentDirectoryId") @@index([parentDirectoryId]) @@index([userId]) }
2. 删除父目录时将子目录设为根目录
如果希望保留子目录,将它们转为根目录,可将onDelete改为SetNull,这样删除父目录时,所有子目录的parentDirectoryId会被设为null:
model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("parentDirectoryId", fields: [parentDirectoryId], references: [id], onDelete: SetNull, onUpdate: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) quizess Quiz[] subDirectory Directory[] @relation("parentDirectoryId") @@index([parentDirectoryId]) @@index([userId]) }
生效步骤
修改Schema后,运行以下命令更新数据库结构:
prisma migrate dev
这会将新的外键约束(级联删除或设为null)同步到数据库,之后再执行prisma.directory.delete()即可正常删除包含子目录的目录。
内容的提问来源于stack exchange,提问作者Filip Pham
相关产品推荐
相关产品推荐

