跳到主要内容

升级到 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 的主要 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 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 之前,存在一个长期存在的错误,导致可空的反向关系在我们生成的类型中未标记为可空。例如,以下 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!