升級到 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 提升為正式可用。這意味著,如果您正在使用 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。
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 作為模型名稱。
預覽特性提升為正式可用
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"]
}