跳至主要内容

升级到 Prisma ORM 5

Prisma ORM 5.0.0 引入了多项变更,包括使用我们新的 JSON 协议,这使得 Prisma Client 默认更快。这些变更的完整列表可以在我们的发布说明中找到。

本指南解释了升级可能如何影响您的应用程序,并提供了如何在 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 的主要版本。

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 Client 嵌入式 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 provider

从 Prisma ORM 5.0.0 版本开始,连接到 CockroachDB 数据库时必须使用 cockroachdb provider。此前,我们也接受 postgresql,但我们正在移除该选项。

如果您使用 原生数据库类型 并且也使用 postgresql provider,您需要将您的数据库从 PostgreSQL 基线化到 CockroachDB

  1. 备份您现有的 schema.prisma 文件(例如,使用版本控制)
  2. 将您的 datasource provider 从 postgresql 更新为 cockroachdb
  3. 使用 npx prisma db pull --force 以覆盖您现有的 Prisma schema(包括原生类型),使其与您的 CockroachDB 实例上的内容一致。
  4. 检查您的 Prisma schema 备份与 db pull 生成的新 Prisma schema 之间的变更。您可以直接使用新 schema,也可以根据您的偏好(例如空格、注释等)进行更新。
  5. 删除您现有的迁移。我们将执行基线化,以使您的本地设置与现有的 CockroachDB 实例保持一致。
  6. 执行基线化步骤。完成这些步骤后,您将成功从 postgresql provider 迁移到 cockroachdb provider!

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

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

使用 @prisma/client/runtime 中的公共 API

在 Prisma ORM 5 中,不再支持从 @prisma/client/runtime 导入。如果您之前使用此命名空间中可用的公共 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 之前,存在一个长期存在的 bug,导致可空的逆向关系在我们生成的类型中未被标记为可空。例如,以下 schema:

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 的变更以避免名称冲突

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

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 属性

generator 块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!

© . This site is unofficial and not affiliated with Prisma Data, Inc.