升級到 Prisma ORM 5
Prisma ORM 5.0.0 引入了許多變更,包括使用我們新的 JSON Protocol,這使得 Prisma Client 預設更快。這些變更的完整列表可以在我們的釋出說明中找到。
本指南解釋了升級可能如何影響您的應用程式,並提供瞭如何處理 Prisma ORM 5 中破壞性變更的說明。
將 prisma 和 @prisma/client 包升級到版本 5
要從早期版本升級到 Prisma ORM 5,您需要更新 prisma 和 @prisma/client 這兩個包。
- npm
- yarn
- pnpm
npm install @prisma/client@5
npm install -D prisma@5
yarn up prisma@5 @prisma/client@5
pnpm upgrade prisma@5 @prisma/client@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 將是 Prisma ORM 支援 Node.js v16 的最後一個主要版本。
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 Protocol,我們現在要求這些運算子的陣列值。
在大多數情況下,修復方法很簡單,只需將現有值包裝在陣列中即可。Prisma ORM 5 中移除的快捷方式有:
雖然 OR、in 和 notIn 運算子受到影響,但 AND 和 NOT 不受此變更影響。
連線到 CockroachDB 資料庫時現在需要 cockroachdb provider
在 Prisma ORM 5.0.0 版本中,我們要求連線到 CockroachDB 資料庫時使用 cockroachdb provider。以前,我們也接受 postgresql,但現在我們正在移除該選項。
如果您之前使用了原生資料庫型別以及 postgresql provider,您將需要將您的資料庫從 PostgreSQL 基線化到 CockroachDB。
- 備份您現有的
schema.prisma檔案(例如,使用版本控制) - 將您的
datasourceprovider 從postgresql更新為cockroachdb - 使用
npx prisma db pull --force以覆蓋您現有的 Prisma schema(包括原生型別),使其與 CockroachDB 例項上的型別一致。 - 審查您的 Prisma schema 備份與
db pull生成的新 Prisma schema 之間的變更。您可以直接使用新 schema,也可以對其進行更新,以包含您偏好的間距、註釋等。 - 刪除您現有的遷移。我們將執行基線化,以使您的本地設定與現有 CockroachDB 例項保持一致。
- 執行基線化步驟。完成這些步驟後,您將成功從
postgresqlprovider 遷移到cockroachdbprovider!
從生成的客戶端中移除 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 之前,存在一個長期存在的 bug,導致可空的逆向關係在我們的生成型別中未被標記為可空。例如,以下 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.user 和 Post.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_items 和 Track.invoice_items,都將獲得型別 InvoiceItemUncheckedUpdateManyWithoutInvoice_itemsInput。在 Prisma ORM 5 中,此問題已解決,Prisma Client 將分別生成 InvoiceItemUncheckedUpdateManyWithoutInvoicesInput 和 InvoiceItemUncheckedUpdateManyWithoutTracksInput。
如果您的程式碼中匯入了生成的型別,您需要將此類例項更新為更正後的型別。
其他變更
以下變更可能導致應用程式在升級到 Prisma ORM 5 後最初丟擲錯誤訊息。幸運的是,它們很容易解決,因為底層功能已移除一段時間,或者變更只是簡單的字串替換。
移除廢棄的 Prisma CLI 標誌
幾個已廢棄的 CLI 標誌已被移除。以下所有標誌均來自舊 API,不再需要:
--preview-feature用於db execute、db seed和db 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 鉤子
beforeExit 鉤子已從 Prisma ORM 庫引擎中移除。雖然此功能對於 Prisma ORM 二進位制引擎仍然需要,以便執行最後的查詢或執行關機相關操作,但它與庫引擎中的原生 Node.js 退出鉤子相比沒有任何優勢。我們建議改用內建的 Node.js 退出事件。
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 鉤子,您可以透過移除服務中的自定義 enableShutdownHooks 方法來升級到 Prisma ORM 5。
@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 方法:
- prismaService.enableShutdownHooks(app)
+ app.enableShutdownHooks()
移除廢棄的 prisma2 可執行檔案
當我們釋出 Prisma ORM 2 時,使用 prisma2 可執行檔案是為了與 Prisma 1 區分。在後來的版本中,prisma2 cli 接管了 prisma 可執行檔案的名稱。
毋庸置疑,prisma2 可執行檔案已經廢棄了一段時間,現在已被移除。如果您的指令碼使用 prisma2 作為 Prisma CLI,請將其替換為簡單的 prisma。
移除廢棄的 experimentalFeatures 屬性
生成器塊的 previewFeatures 欄位以前名為 experimentalFeatures。我們正在移除該廢棄屬性。
在 Prisma ORM 5 中,您需要手動將 experimentalFeatures 的引用更新為 previewFeatures,或者使用 Prisma VSCode 擴充套件中的新程式碼操作。
migration-engine 重新命名為 schema-engine
負責 prisma migrate 和 prisma 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!