升级到 Prisma ORM 6
Prisma ORM v6 引入了许多破坏性变更,如果您从先前的 Prisma ORM 版本升级,请注意。本指南解释了本次升级可能如何影响您的应用程序,并提供了处理任何变更的说明。
升级 prisma
和 @prisma/client
包到 v6
要从早期版本升级到 Prisma ORM v6,您需要更新 prisma
和 @prisma/client
这两个包。
- npm
- yarn
- pnpm
- bun
npm install @prisma/client@6
npm install -D prisma@6
yarn up prisma@6 @prisma/client@6
pnpm upgrade prisma@6 @prisma/client@6
bun add @prisma/client@6
bun add prisma@6 --dev
在升级之前,请检查下面的每个破坏性变更,了解升级可能如何影响您的应用程序。
破坏性变更
本节概述了 Prisma ORM v6 中的破坏性变更。
支持的最低 Node.js 版本
Prisma ORM v6 新支持的最低 Node.js 版本是
- 对于 Node.js 18,支持的最低版本是 18.18.0
- 对于 Node.js 20,支持的最低版本是 20.9.0
- 对于 Node.js 22,支持的最低版本是 22.11.0
官方不支持 Node.js 16、17、19 和 21。
支持的最低 TypeScript 版本
Prisma ORM v6 新支持的最低 TypeScript 版本是:5.1.0。
此 Schema 变更仅适用于 PostgreSQL。
如果您正在使用 CockroachDB,则无需采取任何行动——隐式多对多关系的 Schema 保持不变。
PostgreSQL 上隐式多对多关系的 Schema 变更
如果您正在使用 PostgreSQL 并在 Prisma Schema 中定义隐式多对多关系,Prisma ORM 会在底层为您维护关系表。此关系表包含 A
和 B
列,用于表示作为此关系一部分的模型表。
早期版本的 Prisma ORM 会在这两列上创建一个唯一索引。在 Prisma v6 中,此唯一索引正在更改为主键,以便简化默认的副本身份行为。
展开查看示例
例如,考虑以下 Prisma Schema,其中包含 Post
和 Tag
模型之间的隐式多对多关系
model Post {
id Int @id @default(autoincrement())
title String
categories Tag[]
}
model Tag {
id Int @id @default(autoincrement())
name String
posts Post[]
}
在这种情况下,Prisma ORM 会在底层为您维护以下关系表
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "_PostToTag_AB_unique" ON "_PostToTag"("A", "B");
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
在 Prisma v6 中,UNIQUE INDEX
正在更改为 PRIMARY KEY
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
如果您在 Prisma Schema 中定义了隐式多对多关系,**您创建的下一个迁移将包含针对属于这些关系的所有关系表的 ALTER TABLE
语句**。这些语句将类似于这样
-- AlterTable
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A", "B");
-- DropIndex
DROP INDEX "_PostToTag_AB_unique";
为了隔离这些 Schema 变更(并且不将它们与您的下一个迁移捆绑在一起),**我们建议您在升级到 Prisma v6 后立即创建一个新的迁移**
npx prisma migrate dev --name upgrade-to-v6
这样,您就有一个单独的、专门的迁移来处理此 Schema 变更,并保持您的迁移历史干净。
PostgreSQL 上的全文搜索
fullTextSearch
预览特性仅对 MySQL 提升为正式可用 (General Availability)。这意味着如果您使用 PostgreSQL 并且当前使用了此预览特性,您现在需要使用新的 fullTextSearchPostgres
预览特性
之前
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}
之后
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
}
Buffer
的使用
为了提高 Prisma 与新的现代 JavaScript 运行时之间的兼容性,我们正在逐步放弃 Node.js 特定的 API,转而采用标准的 JavaScript API。
Prisma v6 将使用 Buffer
替换为 Uint8Array
来表示 Bytes
类型的字段。请确保将所有使用 Buffer
类型的地方替换为新的 Uint8Array
。
展开查看如何在 Buffer
和 Uint8Array
之间进行转换
从 Buffer
到 Uint8Array
的转换
您可以直接将 Buffer
实例用作 Uint8Array
const buffer: Buffer = Buffer.from([1, 2, 3, 4]);
const uint8Array: Uint8Array = buffer; // No conversion needed
从 Uint8Array
到 Buffer
的转换
您可以使用 Buffer.from
从 Uint8Array
创建一个 Buffer
const uint8Array: Uint8Array = new Uint8Array([1, 2, 3, 4]);
const buffer: Buffer = Buffer.from(uint8Array.buffer);
之前
- 代码
- Prisma Schema
import { PrismaClient } from '@prisma/client'
async function main() {
const prisma = new PrismaClient()
await prisma.user.deleteMany()
const bytesCreated = await prisma.user.create({
data: {
bytes: Buffer.from([1, 2, 3, 4]),
},
})
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` used to have type: {
// bytes: Buffer
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes // Buffer [ 1, 2, 3, 4 ]
}
}
main()
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
之后
- 代码
- Prisma Schema
import { PrismaClient } from '@prisma/client'
async function main() {
const prisma = new PrismaClient()
await prisma.user.deleteMany()
const bytesCreated = await prisma.user.create({
data: {
bytes: Uint8Array.from([1, 2, 3, 4]),
},
})
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` now has type: {
// bytes: Uint8Array
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes // Uint8Array [ 1, 2, 3, 4 ]
}
}
main()
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
移除 NotFoundError
在 Prisma v6 中,我们移除了 NotFoundError
,转而使用错误代码为 P2025
的 PrismaClientKnownRequestError
在 findUniqueOrThrow()
和 findFirstOrThrow()
中。如果您在代码中依赖于捕获 NotFoundError
实例,则需要相应地调整代码。
之前
import { PrismaClient, NotFoundError } from '@prisma/client';
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (error instanceof NotFoundError) {
console.error("User not found!");
}
else {
console.error("Unexpected error:", error);
}
}
之后
import { PrismaClient, Prisma } from '@prisma/client';
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (
error instanceof Prisma.PrismaClientKnownRequestError &&
error.code === 'P2025' // Specific code for "record not found"
) {
console.error("User not found!");
}
else {
console.error("Unexpected error:", error);
}
}
不能用作模型名称的新关键字:async
, await
, using
在此版本中,您不能再使用 async
, await
和 using
作为模型名称。
预览特性提升为正式可用 (General Availability)
在此版本中,我们将许多预览特性提升为正式可用 (General Availability)。
fullTextIndex
如果您在应用中使用了全文索引特性,您现在可以从 Prisma Schema 的 previewFeatures
中移除 fullTextIndex
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"]
}
fullTextSearch
如果您在应用中与 MySQL 一起使用了全文搜索特性,您现在可以从 Prisma Schema 的 previewFeatures
中移除 fullTextSearch
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}
如果您与 PostgreSQL 一起使用,您需要将特性标志的名称更新为 fullTextSearchPostgres
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
}