跳到主要内容

升级到 Prisma ORM 6

Prisma ORM v6 引入了许多破坏性变更,如果您从先前的 Prisma ORM 版本升级,请注意。本指南解释了本次升级可能如何影响您的应用程序,并提供了处理任何变更的说明。

升级 prisma@prisma/client 包到 v6

要从早期版本升级到 Prisma ORM v6,您需要更新 prisma@prisma/client 这两个包。

npm install @prisma/client@6
npm install -D prisma@6
危险

在升级之前,请检查下面的每个破坏性变更,了解升级可能如何影响您的应用程序。

破坏性变更

本节概述了 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 会在底层为您维护关系表。此关系表包含 AB 列,用于表示作为此关系一部分的模型表。

早期版本的 Prisma ORM 会在这两列上创建一个唯一索引。在 Prisma v6 中,此唯一索引正在更改为主键,以便简化默认的副本身份行为

展开查看示例

例如,考虑以下 Prisma Schema,其中包含 PostTag 模型之间的隐式多对多关系

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 预览特性

之前

schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}

之后

schema.prisma
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

展开查看如何在 BufferUint8Array 之间进行转换

BufferUint8Array 的转换

您可以直接将 Buffer 实例用作 Uint8Array

const buffer: Buffer = Buffer.from([1, 2, 3, 4]);
const uint8Array: Uint8Array = buffer; // No conversion needed

Uint8ArrayBuffer 的转换

您可以使用 Buffer.fromUint8Array 创建一个 Buffer

const uint8Array: Uint8Array = new Uint8Array([1, 2, 3, 4]);
const buffer: Buffer = Buffer.from(uint8Array.buffer);

之前

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()

之后

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()

移除 NotFoundError

在 Prisma v6 中,我们移除了 NotFoundError,转而使用错误代码为 P2025PrismaClientKnownRequestErrorfindUniqueOrThrow()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, awaitusing 作为模型名称。

预览特性提升为正式可用 (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"]
}