You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:35:31