跳至主要内容

升级到 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 提供程序

从 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 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 之前,存在一个长期存在的错误,导致可空的反向关系在生成的类型中未被标记为可空。例如,以下模式:

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 中,您需要手动更新 experimentalFeaturespreviewFeatures 的引用,或者使用 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!