跳到主要内容

升级到 Prisma ORM 6

当您从早期 Prisma ORM 版本升级时,Prisma ORM v6 引入了许多 重大更改。本指南解释了此升级可能对您的应用程序产生的影响,并提供了有关如何处理任何更改的说明。

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

信息

此模式更改仅适用于 PostgreSQL。
如果您正在使用 CockroachDB,则无需执行任何操作——隐式多对多关系的模式保持不变。

PostgreSQL 上隐式多对多关系的模式更改

如果您正在使用 PostgreSQL 并且在 Prisma 模式中定义了 隐式多对多关系,Prisma ORM 会在后台为您维护关系表。此关系表具有 AB 列来表示作为此关系一部分的模型的表。

以前版本的 Prisma ORM 曾经在这两列上创建唯一索引。在 Prisma v6 中,此唯一索引正在更改为主键,以便 简化默认副本标识行为

展开以查看示例

例如,考虑以下 Prisma 模式,其中 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 模式中定义了隐式多对多关系,那么 您创建的下一个迁移将包含用于所有属于这些关系的关系表的 ALTER TABLE 语句。这些语句将类似于这样

-- AlterTable
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A", "B");

-- DropIndex
DROP INDEX "_PostToTag_AB_unique";

为了隔离这些模式更改(并且不将它们与您的下一个迁移捆绑在一起),我们建议您在升级到 Prisma v6 之后立即创建一个新的迁移

npx prisma migrate dev --name upgrade-to-v6

这样,您就拥有了一个单独的专用迁移,它负责处理此模式更改,并保持您的迁移历史记录的整洁。

PostgreSQL 上的全文搜索

fullTextSearch 预览功能仅针对 MySQL 提升为正式版。这意味着如果您正在使用 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。

Prisma v6 将 Buffer 的用法替换为 Uint8Array 以表示 Bytes 类型的字段。请确保将所有出现的 Buffer 类型替换为新的 Uint8Array

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

Buffer 转换为 Uint8Array

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

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

Uint8Array 转换为 Buffer

您可以使用 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,转而使用错误代码为 P2025PrismaClientKnownRequestError,用于 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);
}
}

不能用作模型名称的新关键字:asyncawaitusing

在此版本中,您不能再使用 asyncawaitusing 作为模型名称。

预览功能升级为正式版

在此版本中,我们将许多 预览 功能升级为 正式版

fullTextIndex

如果您在应用程序中使用 全文索引 功能,您现在可以从 Prisma 模式中的 previewFeatures 中移除 fullTextIndex

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

fullTextSearch

如果您在应用程序中将 MySQL全文搜索 功能一起使用,您现在可以从 Prisma 模式中的 previewFeatures 中移除 fullTextSearch

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

如果您将其与 PostgreSQL 一起使用,则需要将功能标志的名称更新为 fullTextSearchPostgres

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