升级到 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
- yarn
- pnpm
npm install @prisma/client@5
npm install -D prisma@5
yarn up prisma@5 @prisma/client@5
pnpm upgrade prisma@5 @prisma/client@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 中移除的快捷方式有:
虽然 OR、in 和 notIn 运算符受到影响,但 AND 和 NOT 不受此变更的影响。
连接到 CockroachDB 数据库时,现在必须使用 cockroachdb provider
从 Prisma ORM 5.0.0 版本开始,连接到 CockroachDB 数据库时必须使用 cockroachdb provider。此前,我们也接受 postgresql,但我们正在移除该选项。
如果您使用 原生数据库类型 并且也使用 postgresql provider,您需要将您的数据库从 PostgreSQL 基线化到 CockroachDB。
- 备份您现有的
schema.prisma文件(例如,使用版本控制) - 将您的
datasourceprovider 从postgresql更新为cockroachdb - 使用
npx prisma db pull --force以覆盖您现有的 Prisma schema(包括原生类型),使其与您的 CockroachDB 实例上的内容一致。 - 检查您的 Prisma schema 备份与
db pull生成的新 Prisma schema 之间的变更。您可以直接使用新 schema,也可以根据您的偏好(例如空格、注释等)进行更新。 - 删除您现有的迁移。我们将执行基线化,以使您的本地设置与现有的 CockroachDB 实例保持一致。
- 执行基线化步骤。完成这些步骤后,您将成功从
postgresqlprovider 迁移到cockroachdbprovider!
从生成的客户端中移除 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.user 和 Post.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_items 和 Track.invoice_items,都将获得类型 InvoiceItemUncheckedUpdateManyWithoutInvoice_itemsInput。在 Prisma ORM 5 中,此问题已解决,Prisma Client 将分别生成 InvoiceItemUncheckedUpdateManyWithoutInvoicesInput 和 InvoiceItemUncheckedUpdateManyWithoutTracksInput。
如果您在代码中导入生成的类型,您将需要将此类实例更新为更正后的类型。
其他变更
以下变更可能会导致应用程序在升级到 Prisma ORM 5 后最初抛出错误消息。幸运的是,它们很容易解决,因为底层功能已经移除了一段时间,或者变更只是一个简单的字符串替换。
移除已弃用的 Prisma CLI 标志
一些已弃用的 CLI 标志已被移除。所有以下标志都来自旧 API,不再需要:
--preview-feature用于db execute、db seed和db 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:
@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 方法:
- 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 migrate 和 prisma 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!