在Next.js中用Prisma Client $extends实现软删除遇阻求助
Prisma软删除实现(针对delete查询)
首先,你需要确保LeaveRequest模型已添加软删除相关字段,示例Schema如下:
model LeaveRequest { id Int @id @default(autoincrement()) // 你的其他业务字段... isDeleted Boolean @default(false) // 标记是否删除 deletedAt DateTime? // 记录删除时间 }
添加字段后运行prisma migrate dev同步数据库结构。
接下来修改你的Prisma初始化代码,正确拦截delete操作并替换为软删除的update:
import { PrismaClient } from "@prisma/client"; const prismaClientSingleton = () => { const prisma = new PrismaClient(); return prisma.$extends({ name: "soft-delete-extension", query: { leaveRequest: { // 拦截单个delete操作 async delete({ args }) { // 复用原delete的where条件,执行软删除更新 return await prisma.leaveRequest.update({ where: args.where, data: { isDeleted: true, deletedAt: new Date() } }); }, // 可选:拦截批量delete操作 async deleteMany({ args }) { return await prisma.leaveRequest.updateMany({ where: args.where, data: { isDeleted: true, deletedAt: new Date() } }); }, // 可选:拦截查询操作,自动过滤已删除数据 async findUnique({ args, query }) { args.where = { ...args.where, isDeleted: false }; return query(args); }, async findMany({ args, query }) { args.where = { ...args.where, isDeleted: false }; return query(args); } } } }); }; declare global { // eslint-disable-next-line no-var var prisma: undefined | ReturnType<typeof prismaClientSingleton>; } const prisma = globalThis.prisma ?? prismaClientSingleton(); export default prisma; if (process.env.NODE_ENV !== "production") globalThis.prisma = prisma;
你之前尝试无效的原因
model.update无法使用:这里的model是字符串类型(如"leaveRequest"),并非Prisma客户端的模型实例,因此不能直接调用update方法。- 修改
operation = "update"无效:operation是只读参数,修改它不会改变底层执行的操作逻辑,原query函数已绑定delete操作,所以该操作无意义。
额外说明
- 如果需要给多个模型添加软删除,可以把拦截逻辑封装成通用函数,避免重复代码。
- 若要彻底禁止物理删除,可考虑拦截
delete和deleteMany后返回提示,或在数据库层面添加触发器限制物理删除。
内容的提问来源于stack exchange,提问作者rionalab
相关产品推荐
相关产品推荐

