跳至主要内容

升级到 Prisma ORM 5

Prisma ORM 5.0.0 引入了许多更改,包括使用我们新的 JSON 协议,这使得 Prisma 客户端默认情况下更快。这些更改的完整列表可以在 我们的发行说明中找到.

本指南解释了升级可能会如何影响您的应用程序,并提供有关如何处理 Prisma ORM 5 中的重大更改的说明。

prisma@prisma/client 包升级到版本 5

要从早期版本升级到 Prisma ORM 5,您需要更新 prisma@prisma/client 包。

npm install @prisma/client@5
npm install -D prisma@5
危险

在升级之前,请检查下面每个重大更改,以查看升级可能会如何影响您的应用程序。

版本更改

Prisma ORM 5 包含一些针对 Node.js、TypeScript 和 PostgreSQL 的最低版本更改。要使用 Prisma 版本 5.0.0 及更高版本,您需要至少具有以下最低版本:有关所有最低版本要求,请参阅我们的 系统要求

Node.js 最低版本更改

从 Prisma ORM 版本 5.0.0 开始,支持的 Node.js 最低版本是 16.13.0。如果您的项目使用的是早期版本的 Node.js,则需要对其进行升级。

警告

Node.js v16.x 即将在 2023 年 9 月 11 日生命周期结束,以配合 OpenSSL 1.1.1 的生命周期结束。因此,我们建议升级到当前的 Node.js LTS,v18.x。请注意,Prisma ORM 5 将是最后一个支持 Node.js v16 的主要 Prisma ORM 版本。

TypeScript 最低版本更改

从 Prisma ORM 版本 5.0.0 开始,支持的 TypeScript 最低版本是 4.7。如果您的项目使用的是早期版本的 TypeScript,则需要对其进行升级。

PostgreSQL 最低版本更改

从 Prisma ORM 版本 5.0.0 开始,支持的 PostgreSQL 最低版本是 9.6。如果您的项目使用的是早期版本的 PostgreSQL,则需要对其进行升级。

警告

虽然 Prisma ORM 支持 PostgreSQL 版本 9.6 及更高版本,但我们强烈建议您更新到当前支持且仍在接收更新的版本。请检查 PostgreSQL 的版本控制策略 以确定当前支持哪些版本。

Prisma 客户端嵌入式 SQLite 版本更新

在 Prisma ORM 版本 5.0.0 中,我们将嵌入式 SQLite 版本从 3.35.4 升级到 3.41.2。我们没有看到任何重大更改,也不预计用户项目中需要任何更改,但如果您使用的是 SQLite,特别是使用可能超出 Prisma ORM 功能的原始查询,请务必检查 SQLite 变更日志.

主要更改

本节概述了 Prisma ORM 5 中的主要重大更改。

删除 rejectOnNotFound 参数

在 Prisma ORM 5 中,已弃用的参数 rejectOnNotFound 已被删除。根据您的项目是按查询使用 rejectOnNotFound 还是全局使用,更新代码的方式会有所不同。

如果您在按查询的基础上使用 rejectOnNotFound 参数,请按照我们的步骤操作,以 在查询级别更新您的代码

如果您是在客户端级别设置 rejectOnNotFound 参数,则需要按照 在客户端级别更新代码的步骤 进行操作。

jsonProtocol 退出预览

jsonProtocol 预览功能现在已正式发布。与我们之前的基于 GraphQL 的协议相比,此新协议可 显著缩短启动时间。升级到 Prisma ORM 5 时,请确保从预览功能中删除 jsonProtocol(如果已添加)。

Prisma ORM 4 及更低版本

generator client {
provider = "prisma-client-js"
previewFeatures = ["jsonProtocol"]
}

Prisma ORM 5

generator client {
provider = "prisma-client-js"
}

请查看我们的 jsonProtocol 更改指南,了解如何更新您的应用程序以考虑 Prisma ORM 5 中的新协议。您需要

删除数组快捷方式

Prisma ORM 5 不再支持许多“数组快捷方式”。这些快捷方式是将单个元素作为值添加到基于数组的操作符的一种方法,而不是将该元素包装在数组中。为了使我们的类型更一致和合乎逻辑,并符合新的 JSON 协议,我们现在要求这些操作符使用数组值。

在大多数情况下,修复就像将现有值包装在数组中一样简单。在 Prisma ORM 5 中删除的快捷方式包括

虽然 ORinnotIn 操作符受到影响,但 ANDNOT 操作符不受此更改的影响。

连接到 CockroachDB 数据库时,cockroachdb 提供程序现在是必需的

在 Prisma ORM 版本 5.0.0 中,我们要求在连接到 CockroachDB 数据库时使用 cockroachdb 提供程序。以前,我们也接受 postgresql,但现在我们正在删除该选项。

如果您使用的是 本机数据库类型 以及 postgresql 提供程序,则需要 将您的数据库从 PostgreSQL 基线化到 CockroachDB

  1. 备份您现有的schema.prisma文件(例如使用版本控制)。
  2. 将您的datasource提供程序从postgresql更新为cockroachdb
  3. 使用npx prisma db pull --force覆盖您现有的 Prisma 架构(包括原生类型),以匹配您的 CockroachDB 实例上的架构。
  4. 检查您的 Prisma 架构备份和 db pull 生成的新的 Prisma 架构之间的差异。您可以直接使用新的架构,或者更新它以包含您首选的间距、注释等。
  5. 删除您现有的迁移。我们将执行基线操作,以使您的本地设置与您的现有 CockroachDB 实例一致。
  6. 执行基线操作步骤。完成这些步骤后,您将成功从 postgresql 提供程序迁移到 cockroachdb 提供程序!

从生成的客户端中删除 runtime/index.js

runtime/index.js 文件已从 Prisma Client 中删除。

使用来自 @prisma/client/runtime 的公共 API

@prisma/client/runtime 中导入不再在 Prisma ORM 5 中可用。如果您之前使用过此命名空间中可用的公共 API,则可以改为导入 Prisma 并访问它们。例如

import { Decimal, NotFoundError } from '@prisma/client/runtime'
const num = new Decimal(24.454545)
const notFound = new NotFoundError()

需要更改为

import { Prisma } from '@prisma/client'
const num = new Prisma.Decimal(24.454545)
const notFound = new Prisma.NotFoundError()

使用特定运行时的私有 API

我们强烈建议不要使用内部私有 API,因为它们可能会在没有任何警告的情况下发生更改,并且不能保证得到支持。如果您使用需要以前可用的私有 API请在 GitHub 上联系我们。

生成的类型更改

更改 RelationFilterInput 以考虑可空性

在 Prisma ORM 5 之前,存在一个长期存在的错误,导致可空的反向关系在我们生成的类型中没有被标记为可空。例如,考虑以下架构

model User {
id Int @id

addressId Int @unique
address Address @relation(fields: [addressId], references: [id])

post Post[]
}

model Address {
id Int @id

user User?
}

model Post {
id Int @id

userId Int
user User @relation(fields: [userId], references: [id])
}

在生成的类型中,Address.userPost.user 将使用相同的类型 UserRelationFilter。这显然是意料之外的,因为 Address.user 是可空的,而 Post.user 不是。在 Prisma ORM 5 中,Address.user 的类型将是 UserNullableRelationFilter,从而解决了此问题。

如果您在代码中导入生成的类型,则需要更新类似这种情况的实例以使用新的 Nullable 类型。

更改 UncheckedUpdateManyInput 以避免名称冲突

在某些情况下,当一个模型有两个外键指向另外两个模型时,可能会发生名称冲突,而另外两个模型的反向关系具有相同的属性名称。例如,以下架构

model Invoice {
InvoiceId Int @id @default(autoincrement())

invoice_items InvoiceItem[]
}

model InvoiceItem {
InvoiceLineId Int @id @default(autoincrement())

InvoiceItemInvoiceId Int @map("InvoiceId")
invoices Invoice @relation(fields: [InvoiceItemInvoiceId], references: [InvoiceId])

TrackId Int
tracks Track @relation(fields: [TrackId], references: [TrackId])
}

model Track {
TrackId Int @id @default(autoincrement())
Name String

invoice_items InvoiceItem[]
}

将导致 InvoiceItem 上的两个关系之间出现名称冲突。反向关系,即 Invoice.invoice_itemsTrack.invoice_items 都将获得类型 InvoiceItemUncheckedUpdateManyWithoutInvoice_itemsInput。在 Prisma ORM 5 中,这个问题已解决,Prisma Client 将分别生成 InvoiceItemUncheckedUpdateManyWithoutInvoicesInputInvoiceItemUncheckedUpdateManyWithoutTracksInput

如果您在代码中导入生成的类型,则需要将类似这种情况的实例更新为已更正的类型。

其他更改

以下更改可能会导致应用程序在升级到 Prisma ORM 5 后最初抛出错误消息。幸运的是,它们很容易解决,因为底层功能已被移除了一段时间,或者更改只是一个简单的字符串替换。

删除弃用的 Prisma CLI 标志

已删除几个弃用的 CLI 标志。以下所有标志来自以前的 API,不再需要

  • --preview-feature 用于 db executedb seeddb diff
  • --experimental--early-access-feature 用于 migrate
  • --force/-f 用于 db push
  • --experimental-reintrospection--clean 用于 db pull

过时的 db push --force 的使用可以替换为更新的实现 db push --accept-data-loss

所有其他标志来自以前的 API,不再需要。

从库引擎中删除 beforeExit 钩子

beforeExit 钩子已从 Prisma ORM 库引擎中删除。虽然此功能对于 Prisma ORM 二进制引擎仍然是必需的,以便运行最后一分钟的查询或执行与关闭相关的操作,但在库引擎中它没有比本机 Node.js 退出钩子更好的优势。我们建议您使用内置的 Node.js 退出事件,而不是使用此钩子。

使用 Prisma ORM 4 的以下代码

const exitHandler = () => {
// your exit handler code
}

prisma.$on('beforeExit', exitHandler)

可以变成

const exitHandler = () => {
// your exit handler code
}

process.on('exit', exitHandler)
process.on('beforeExit', exitHandler)
process.on('SIGINT', exitHandler)
process.on('SIGTERM', exitHandler)
process.on('SIGUSR2', exitHandler)

如果您在 NestJS 中使用 beforeExit 钩子,可以通过删除服务中的自定义 enableShutdownHooks 方法来升级到 Prisma ORM 5

"prisma.service.ts"
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect()
}

- async enableShutdownHooks(app: INestApplication) {
- this.$on('beforeExit', async () => {
- await app.close()
- })
- }
}

如果需要处理生命周期事件,请改用 NestJS 中的内置 enableShutdownHooks 方法

"main.ts"
- prismaService.enableShutdownHooks(app)
+ app.enableShutdownHooks()

删除弃用的 prisma2 可执行文件

当我们发布 Prisma ORM 2 时,prisma2 可执行文件用于与 Prisma 1 区分。在以后的版本中,prisma2 cli 接管了 prisma 可执行文件名称。

不用说,prisma2 可执行文件已经过时一段时间,现在已被删除。如果您的脚本将 Prisma CLI 用作 prisma2,请将其替换为 prisma

删除弃用的 experimentalFeatures 属性

生成器块previewFeatures 字段以前称为 experimentalFeatures。我们正在删除该弃用的属性。

在 Prisma ORM 5 中,您需要手动将 experimentalFeatures 的引用更新为 previewFeatures,或者使用 Prisma VSCode 扩展中的新代码操作。

migration-engine 重命名为 schema-engine

负责 prisma migrateprisma db 等命令的引擎已从 migration-engine 重命名为 schema-engine,以更好地描述其用途。对于许多用户来说,不需要进行任何更改。但是,如果您需要显式包含或排除此引擎文件,或者出于任何其他原因引用引擎名称,则需要更新代码引用。

使用 Serverless Framework 的示例

我们看到的一个例子是使用 Serverless Framework 的项目。在这种情况下,您需要将所有引用 migration-engine 的模式更新为引用 schema-engine

package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-rhel-*'
- '!node_modules/prisma/libquery_engine-*'
-- '!node_modules/prisma/migration-engine-*'
-- '!node_modules/prisma/schema-engine-*'
Serverless Framework 模式建议

我们的文档中的推荐规则不受此更改的影响,因为它排除了所有不需要的引擎文件。

package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-rhel-*'
- '!node_modules/prisma/libquery_engine-*'
-- '!node_modules/@prisma/engines/**'

享受 Prisma ORM 5!