跳至主要內容

升級至 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 install @prisma/client@5
npm install -D prisma@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 的 Prisma ORM 主要版本。

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 中移除的快捷方式包括

雖然 ORinnotIn 運算符受到影響,但 ANDNOT 不受此變更影響。

連線到 CockroachDB 資料庫時,現在需要 cockroachdb 提供者

在 Prisma ORM 5.0.0 版本中,我們要求在連線到 CockroachDB 資料庫時使用 cockroachdb 提供者。以前,我們也接受 postgresql,但我們正在移除該選項。

如果您正在使用 原生資料庫類型 以及 postgresql 提供者,您將需要將您的資料庫從 PostgreSQL 基準化到 CockroachDB

  1. 備份您現有的 schema.prisma 檔案(例如,使用版本控制)
  2. 將您的 datasource 提供者從 postgresql 更新為 cockroachdb
  3. 使用 npx prisma db pull --force 以覆寫您現有的 Prisma schema(包括原生類型)為 CockroachDB 實例上的那些。
  4. 查看您的 Prisma schema 備份與 db pull 產生的新 Prisma schema 之間的變更。您可以直接使用新的 schema,或更新它以包含您偏好的間距、註解等。
  5. 刪除您現有的遷移。我們將執行基準化,以使您的本機設定與您現有的 CockroachDB 實例一致。
  6. 執行基準化步驟。完成這些步驟後,您將成功地從 postgresql 提供者遷移到 cockroachdb 提供者!

從產生的用戶端中移除 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 之前,存在一個長期存在的錯誤,導致可空的反向關係在我們產生的類型中未標記為可空。例如,採用以下 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.userPost.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_itemsTrack.invoice_items 都將獲得類型 InvoiceItemUncheckedUpdateManyWithoutInvoice_itemsInput。在 Prisma ORM 5 中,此問題已解決,Prisma Client 將分別產生 InvoiceItemUncheckedUpdateManyWithoutInvoicesInputInvoiceItemUncheckedUpdateManyWithoutTracksInput

如果您在程式碼中匯入產生的類型,您將需要將此類實例更新為更正的類型。

其他變更

以下變更可能會導致應用程式在升級到 Prisma ORM 5 後最初擲回錯誤訊息。幸運的是,它們很容易解決,因為底層功能已移除一段時間,或者變更只是簡單的字串替換。

移除已棄用的 Prisma CLI 標誌

已移除多個已棄用的 CLI 標誌。以下所有標誌都來自先前的 API,並且不再需要

  • --preview-feature 用於 db executedb seeddb 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 hook

beforeExit hook 已從 Prisma ORM 程式庫引擎中移除。雖然此功能對於 Prisma ORM 二進位引擎仍然是必需的,以便執行最後一分鐘的查詢或執行關閉相關的操作,但它在程式庫引擎中沒有優於原生 Node.js exit hook 的優勢。我們建議使用內建的 Node.js exit 事件來代替此 hook。

以下是使用 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 hook,您可以透過移除服務中的自訂 enableShutdownHooks 方法來升級到 Prisma ORM 5

「prisma.service.ts」
@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 方法

「main.ts」
- prismaService.enableShutdownHooks(app)
+ app.enableShutdownHooks()

移除已棄用的 prisma2 可執行檔

當我們發布 Prisma ORM 2 時,使用了 prisma2 可執行檔,以便與 Prisma 1 區分開來。在後續版本中,prisma2 cli 接管了 prisma 可執行檔名稱。

毋庸置疑,prisma2 可執行檔已被棄用一段時間,現在已移除。如果您的腳本將 Prisma CLI 用作 prisma2,請將其替換為簡單的 prisma

移除已棄用的 experimentalFeatures 屬性

產生器區塊previewFeatures 欄位以前稱為 experimentalFeatures。我們正在移除該已棄用的屬性。

在 Prisma ORM 5 中,您將需要手動更新 experimentalFeatures 的參考為 previewFeatures,或使用 Prisma VSCode 擴充功能中的新程式碼動作。

migration-engine 重新命名為 schema-engine

負責 prisma migrateprisma 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!