@candoimage/prisma-extension-soft-delete

中文文档
2.1.3发布于 2026/07/28Apache-2.0TypeScriptESM + CJS近 30 天下载 2万

软删除记录的 Prisma 扩展名 - Prisma 7 兼容叉

中文使用文档
文档目录14 节
  1. Prisma 7 兼容性
  2. 限制
  3. 目录
  4. 安装
  5. 使用量
  6. 扩展设置
  7. Prisma Schema 设置
  8. 行为
  9. 删除记录
  10. 不包括软被删除的记录
  11. 更新记录
  12. 对象
  13. 包括或选择被软删除的记录
  14. 自由主义

@ candoimage/prisma-extension-soft-delete (英语)

Prisma 7 兼容 用于软删除记录的扩展名.

这是叉子 棱镜-扩展-软-删除 (通过) 圆通现金叉与 Prisma 7 兼容性修正。 。 。 .

软删除记录是许多应用程序中常见的模式. 此库为 Prisma 提供扩展名 允许您软化删除记录并将其排除在查询之外。 它处理通过关系删除记录和 在将关系包括在内或将关系参考到对象时,排除被软删除的记录。 它通过使用 页:1 棱镜 -- -- 延伸 -- -- 确认操作 用于处理嵌入式关系的库.


Prisma 7 兼容性

这个叉子包括以下Prisma 7的修饰:

  1. 独有字段 DMMF 修正: Prisma 7 已删除 uniqueFields 来自DMMF模型结构. 这个叉子增加了一个倒置来防止相撞.

  2. 包含/选择固定位置: Prisma 7 不再允许 where 内部 include 用于一对一关系的块。 此叉只添加 where 用于多个(列表)关系的过滤器.

限制

  • 化合物独特指数@@unique)由于Prisma 7 DMMF的修改,没有得到充分的支持
  • 使用 findFirst 明确 deletedAt: null 具有化合物独有密钥的模型过滤器

Build Status version MIT License semantic-release PRs Welcome

目录

安装

此模块通过 无 并且应该安装为您的其中之一 项目的依赖性 :

npm install @candoimage/prisma-extension-soft-delete

@prisma/client 是此库的对等依赖, 因此您需要 如果您还没有安装它 :

npm install @prisma/client

使用量

扩展设置

要将软删除功能添加到您的 Prisma 客户端中, 请使用 createSoftDeleteExtension 函数并传递给 client.$extends。 。 。 .

这个 createSoftDeleteExtension 函数使用一个配置对象,用于定义要使用软模型 删除时使用.

import { PrismaClient } from "@prisma/client";

const client = new PrismaClient();

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: true,
    },
  })
);

默认情况下,扩展将使用 deleted 类型字段 Boolean 在模型上。 如果您想要使用自定义字段 您可以为模型通过一个配置对象。 例如使用一个 deletedAt 值为空的字段 默认和 a DateTime 当记录被删除时,您会通过以下文件:

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: {
        field: "deletedAt",
        createValue: (deleted) => {
          if (deleted) return new Date();
          return null;
        },
      },
    },
  })
);

这个 field 属性是用于软删除的字段的名称 createValue 属性是函数 取一个被删除的参数,并返回记录是否被软删除的值。 这个 createValue 方法 如果记录不删除,则必须返回 falsy 值,如果删除,则必须返回 truth 值.

可以通过在 models 对象 :

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: true,
      Post: true,
    },
  })
);

要修改所有模型的默认字段和类型, 您可以通过一个 defaultConfig数字 :

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: true,
      Post: true,
    },
    defaultConfig: {
      field: "deletedAt",
      createValue: (deleted) => {
        if (deleted) return new Date();
        return null;
      },
    },
  })
);

当使用默认配置时,您也可以通过传递一个配置对象来覆盖特定模型的默认配置 该模型:

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: true,
      Post: {
        field: "deleted",
        createValue: Boolean,
      },
    },
    defaultConfig: {
      field: "deletedAt",
      createValue: (deleted) => {
        if (deleted) return new Date();
        return null;
      },
    },
  })
);

配置对象还有一个 allowToOneUpdates 选项,用于通过 巢所更新. 默认设置为 false 如果您尝试更新一个 toone 关系, 将会出错 通过一个嵌入式更新。 如果你想允许,你可以设定 allowToOneUpdates 改为 true数字 :

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: {
        field: "deleted",
        createValue: Boolean,
        allowToOneUpdates: true,
      },
    },
  })
);

关于为何通过 toone 关系默认禁用更新的更多信息,请参见: 更新记录 节.

与 allowToOneUpdates 有一个 allowCompoundUniqueIndexWhere 选项,可用于允许使用 中,在使用时带有化合物独有索引字段的对象 findUnique 查询。 默认设置为 false 财务报告和审定财务报表 如果您尝试使用一个带有化合物独有索引字段的地方,则会显示错误。 如果你想允许,你可以设定 allowCompoundUniqueIndexWhere 改为 true数字 :

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      Comment: {
        field: "deleted",
        createValue: Boolean,
        allowCompoundUniqueIndexWhere: true,
      },
    },
  })
);

关于为何通过 toone 关系默认禁用更新的更多信息,请参见: 不包括 a 中被软删除的记录 findUnique 运行 节.

要在全球范围内允许一个更新或复合独特的索引字段,您可以使用 defaultConfig 2. 这样做:

const extendedClient = client.$extends(
  createSoftDeleteExtension({
    models: {
      User: true,
      Comment: true,
    },
    defaultConfig: {
      field: "deleted",
      createValue: Boolean,
      allowToOneUpdates: true,
      allowCompoundUniqueIndexWhere: true,
    },
  })
);

Prisma Schema 设置

Prisma 方案必须更新,以包括您想要使用软删除的每个模型的软删除字段.

要使用默认字段和类型配置的模型,您必须添加 deleted 字段到您的 Prisma 计划. 使用配置于 扩展设置 您需要添加以下内容: Prisma 计划 :

model Comment {
  deleted   Boolean  @default(false)
  [other fields]
}

如果注释模型配置为使用 deletedAt 字段中默认值无效的值和 a DateTime 何时 您需要在您的 Prisma 计划中添加以下内容:

model Comment {
  deletedAt DateTime?
  [other fields]
}

配置用于使用软删除的模型,通过 toOne 关系与其他模型相关,必须具有此功能 被定义为可选关系。 这是因为扩展将排除关系时被软删除的记录 包含或选择。 如果关系不是可选的,那么关系的类型是不正确的,您可以 得到运行时间错误.

例如,如果你有一个 author 注释模型上的关系和用户模型的配置以使用软 删除需要更改关系为可选 :

model Comment {
  authorId Int?
  author   User?   @relation(fields: [authorId], references: [id])
  [other fields]
}

@unique 字段,用于使用软删除的模型,由于记录实际上不是,可能会造成问题 正在删除。 如果一个记录被软删除,然后创建一个新的记录,对独有的字段具有相同的价值, 无法创建新记录 .

行为

扩展的主要行为是将删除操作替换为设置软删除的更新操作 字段为已删除的值.

扩展也通过排除软被删除的记录来防止意外获取或更新被软被删除的记录 从查找查询、包括、选择和批量更新。 扩展允许对软删除进行明确查询 并允许通过独特的字段进行更新,例如它是 id. 它允许通过独特的字段更新的原因是 因为软被删除的记录只能被明确地取出,所以通过一个独特的字段更新应该是有意的.

删除记录

使用 delete 或者说 deleteMany 操作扩展将更改为 update 操作并设定软删除字段为该模型配置中定义的被删除值.

例如,如果配置了注释模型以使用默认 deleted 类型字段 Boolean 扩展名 将会改变 delete 操作到一个 update 操作和设置 deleted 字段改为 true。 。 。 .

删除单一记录

使用 delete 操作 :

await client.comment.delete({
  where: {
    id: 1,
  },
});

延长的操作将改为:

await client.comment.update({
  where: {
    id: 1,
  },
  data: {
    deleted: true,
  },
});

删除多个记录

使用 deleteMany 操作 :

await client.comment.deleteMany({
  where: {
    id: {
      in: [1, 2, 3],
    },
  },
});

延长的操作将改为:

await client.comment.updateMany({
  where: {
    id: {
      in: [1, 2, 3],
    },
  },
  data: {
    deleted: true,
  },
});

通过关系删除

当通过关系使用嵌入式删除时,扩展会将嵌入式删除操作更改为更新 操作 :

await client.post.update({
  where: {
    id: 1,
  },
  data: {
    comments: {
      delete: {
        where: {
          id: 2,
        },
      },
    },
    author: {
      delete: true,
    },
  },
});

延长的操作将改为:

await client.post.update({
  where: {
    id: 1,
  },
  data: {
    comments: {
      update: {
        where: {
          id: 2,
        },
        data: {
          deleted: true,
        },
      },
    },
    author: {
      update: {
        deleted: true,
      },
    },
  },
});

在使用巢穴时,同样的行为也一样 deleteMany 和曼尼的关系.

硬删除

当 extendedWhereUnique 特性被支持 可以明确硬删除软被删除的记录。 同时你可以使用 executeRaw 操作以执行硬删除.

不包括软被删除的记录

使用时 findUnique, (中文(简体) ), findFirst 财务报告和审定财务报表 findMany 操作 where 通过对象 排除被软删除的记录。 为此,它增加了一个附加条件 where 排除对象 将软删除字段设置为该模型配置中定义的已删除值.

不包括 a 中被软删除的记录 findFirst 运行

当使用一个 findFirst 操作扩展将修改 where 反对排除被软删除的记录,因此:

await client.comment.findFirst({
  where: {
    id: 1,
  },
});

延长的操作将改为:

await client.comment.findFirst({
  where: {
    id: 1,
    deleted: false,
  },
});

不包括 a 中被软删除的记录 findMany 运行

当使用一个 findMany 操作扩展将修改 where 反对排除被软删除的记录,因此:

await client.comment.findMany({
  where: {
    id: 1,
  },
});

延长的操作将改为:

await client.comment.findMany({
  where: {
    id: 1,
    deleted: false,
  },
});

不包括 a 中被软删除的记录 findUnique 运行

当使用一个 findUnique 操作扩展名将更改要使用的查询 findFirst 这样它就可以修改 where 反对排除被软删除的记录,因此:

await client.comment.findUnique({
  where: {
    id: 1,
  },
});

延长的操作将改为:

await client.comment.findFirst({
  where: {
    id: 1,
    deleted: false,
  },
});

当在对象所在处使用化合物独有索引进行查询时,扩展将默认丢出一个出错. 这个 因为不可能使用这些类型的对象 findFirst 无法排除 使用时被软删除的记录 findUnique。例如,请查询如下:

await client.user.findUnique({
  where: {
    name_email: {
      name: "foo",
      email: "bar",
    },
  },
});

由于化合物独特的指数 @@unique([name, email]) 正在通过 name_email 区域 对象,扩展将丢弃以避免意外返回软被删除的记录.

通过设置可以推翻此行为 allowCompoundUniqueIndexWhere 改为 true 在模型配置中.

更新记录

更新记录分为三类,使用根操作更新单个记录,更新单个记录 通过关系记录和通过根操作或关系更新多个记录.

使用根操作更新单个记录时, 例如 update 或者说 upsert 扩展将不会修改 操作。 这是因为除非明确询问软被删除的记录,否则不应从询问中退回, 因此,如果这些行动正在更新一个被软删除的记录,那应该是有意的.

在通过关系更新单个记录时,扩展将默认出现出错. 这是因为它 无法过滤已嵌入到 One 关系的被软删除的记录 。 例如,请查询如下:

await client.post.update({
  where: {
    id: 1,
  },
  data: {
    author: {
      update: {
        name: "foo",
      },
    },
  },
});

自从 author 字段是一个“One”关系,它不支持对象所在。 这意味着如果 author 字段 是一个软被删除的记录,它将不慎被更新.

通过设置可以推翻此行为 allowToOneUpdates 改为 true 在扩展配置中.

使用 updateMany 扩展将修改 where 为排除软而通过的对象 删除记录。 例如,请查询如下:

await client.comment.updateMany({
  where: {
    id: 1,
  },
  data: {
    content: "foo",
  },
});

延长的操作将改为:

await client.comment.updateMany({
  where: {
    id: 1,
    deleted: false,
  },
  data: {
    content: "foo",
  },
});

当更新一个与 Many 的关系时, 这一点也会起作用 :

await client.post.update({
  where: {
    id: 1,
  },
  data: {
    comments: {
      updateMany: {
        where: {
          id: 1,
        },
        data: {
          content: "foo",
        },
      },
    },
  },
});

延长的操作将改为:

await client.post.update({
  where: {
    id: 1,
  },
  data: {
    comments: {
      updateMany: {
        where: {
          id: 1,
          deleted: false,
        },
        data: {
          content: "foo",
        },
      },
    },
  },
});

明确更新许多被软删除的记录

使用时 updateMany 操作中可以通过设置 删除字段到该模型配置中定义的已删除值。 用于更新软删除的示例 记录如下:

await client.comment.updateMany({
  where: {
    content: "foo",
    deleted: true,
  },
  data: {
    content: "bar",
  },
});

对象

当使用一个 where 查询可以使用为使用软删除而配置的参考模型。 在这种情况下 扩展将修改 where 反对将软被删除的记录排除在查询之外,因此:

await client.post.findMany({
  where: {
    id: 1,
    comments: {
      some: {
        content: "foo",
      },
    },
  },
});

延长的操作将改为:

await client.post.findMany({
  where: {
    id: 1,
    comments: {
      some: {
        content: "foo",
        deleted: false,
      },
    },
  },
});

当对象包含逻辑运算符时,此操作也会起作用:

await client.post.findMany({
  where: {
    id: 1,
    OR: [
      {
        comments: {
          some: {
            author: {
              name: "Jack",
            },
          },
        },
      },
      {
        comments: {
          none: {
            author: {
              name: "Jill",
            },
          },
        },
      },
    ],
  },
});

延长的操作将改为:

await client.post.findMany({
  where: {
    id: 1,
    OR: [
      {
        comments: {
          some: {
            deleted: false,
            author: {
              name: "Jack",
            },
          },
        },
      },
      {
        comments: {
          none: {
            deleted: false,
            author: {
              name: "Jill",
            },
          },
        },
      },
    ],
  },
});

使用时 every 修改扩展将修改 where 反对将软被删除的记录排除在 以不同方式查询,例如:

await client.post.findMany({
  where: {
    id: 1,
    comments: {
      every: {
        content: "foo",
      },
    },
  },
});

延长的操作将改为:

await client.post.findMany({
  where: {
    id: 1,
    comments: {
      every: {
        OR: [{ deleted: { not: false } }, { content: "foo" }],
      },
    },
  },
});

这是因为如果用同样的逻辑 some 财务报告和审定财务报表 none 用于: every 然后查询会 失败.

删除的大小写使用 not 运算符,以确保查询对自定义字段和类型有效。 例如,如果 字段被配置为 deletedAt 类型所在 DateTime 删除时 null 当不删除时,则 查询为:

await client.post.findMany({
  where: {
    id: 1,
    comments: {
      every: {
        OR: [{ deletedAt: { not: null } }, { content: "foo" }],
      },
    },
  },
});

明确查询被删除的软记录

可以通过设置已配置的字段来明确查询软被删除的记录 where 对象。 对于 实例如下:

await client.comment.findMany({
  where: {
    deleted: true,
  },
});

也可以通过在 where 对象。 举个例子 以下内容也将不会被修改:

await client.post.findMany({
  where: {
    comments: {
      some: {
        deleted: true,
      },
    },
  },
});

包括或选择被软删除的记录

使用时 include 或者说 select 扩展将修改 include 财务报告和审定财务报表 select 为排除软而传递的物体 删除记录.

包括或选择到多种关系

使用时 include 或者说 select 在多个关系上,扩展将修改对象的位置以排除软 从查询中删除记录, 用于:

await client.post.findMany({
  where: {
    id: 1,
  },
  include: {
    comments: true,
  },
});

如果注释模型配置为被软删除,扩展将修改 include 反对时的行动 不包括被删除的软记录,因此查询将:

await client.post.findMany({
  where: {
    id: 1,
  },
  include: {
    comments: {
      where: {
        deleted: false,
      },
    },
  },
});

这同样适用于 select数字 :

await client.post.findMany({
  where: {
    id: 1,
  },
  select: {
    comments: true,
  },
});

这也适用于被巢所覆盖的包括和选择:

await client.user.findMany({
  where: {
    id: 1,
  },
  include: {
    posts: {
      select: {
        comments: {
          where: {
            content: "foo",
          },
        },
      },
    },
  },
});

该扩展将修改查询内容为:

await client.user.findMany({
  where: {
    id: 1,
  },
  include: {
    posts: {
      select: {
        comments: {
          where: {
            deleted: false,
            content: "foo",
          },
        },
      },
    },
  },
});

包括或选择一个关系

也排除通过 " 一个关系 " 列入的记录,但无法明确列入这些记录。 对于 示例如下:

await client.post.findFirst({
  where: {
    id: 1,
  },
  include: {
    author: true,
  },
});

扩展不会修改查询,因为一个关系不支持条款。 代替扩展 将基于已配置的已删除字段手动过滤结果.

因此,如果"邮报"作者被软删除,扩展会过滤结果并删除作者 结果 :

{
  id: 1,
  title: "foo",
  author: null
}

在 to One 关系上选择特定字段时,扩展将手动将所配置的已删除字段添加到 选择对象,过滤结果并最后从结果中去掉被删除的字段后再返回.

例如,下面的查询会这样做:

await client.post.findMany({
  where: {
    id: 1,
  },
  select: {
    author: {
      select: {
        name: true,
      },
    },
  },
});

将软被删除的记录明确纳入到多个关系中

可以通过将所配置的已删除字段添加到 页:1 where 对象。 例如,以下将包括在结果中被删除的记录:

await client.post.findMany({
  where: {
    id: 1,
  },
  include: {
    comments: {
      where: {
        deleted: true,
      },
    },
  },
});

自由主义

Apache 2.0 (英语)

版本与发布记录

@candoimage/prisma-extension-soft-delete 共发布 6 个版本,首次发布于 2025/12/11;过去 12 个月发布了 6 个版本。

版本发布日期距今
2.1.3latest2026/07/283 个月前
2.1.22026/03/307 个月前
2.1.12026/03/028 个月前
2.1.02025/12/1110 个月前
2.0.12025/12/1110 个月前
2.0.02025/12/1110 个月前

关于 @candoimage/prisma-extension-soft-delete 的常见问题

@candoimage/prisma-extension-soft-delete 是什么?

软删除记录的 Prisma 扩展名 - Prisma 7 兼容叉

如何安装 @candoimage/prisma-extension-soft-delete?

在项目目录运行 npm install @candoimage/prisma-extension-soft-delete,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@prisma/client(>=7.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@candoimage/prisma-extension-soft-delete 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@candoimage/prisma-extension-soft-delete 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@candoimage/prisma-extension-soft-delete 可以商用吗?

@candoimage/prisma-extension-soft-delete 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@candoimage/prisma-extension-soft-delete 的下载量有多少?

根据 npm 官方下载统计,@candoimage/prisma-extension-soft-delete 在 2026/10/09 – 2026/11/07 这 30 天内被下载 20,025 次,日均约 668 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@candoimage/prisma-extension-soft-delete 还在维护吗?

最新版本 2.1.3 发布于 2026/07/28(3 个月前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2025/12/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。