升級至 Prisma ORM 4
從較早的 Prisma ORM 版本升級時,Prisma ORM 4 引入了許多重大變更。本指南說明此升級可能如何影響您的應用程式,並提供關於如何處理任何變更的說明。
重大變更
本節概述 Prisma ORM 4 中的重大變更,分為影響 Prisma Schema 和 Prisma Client 的一般變更、Schema 變更和Client 變更。
我們建議您先解決任何 Prisma schema 驗證錯誤,然後提取您的資料庫以反映新的 Prisma schema 功能,最後修復 Prisma Client 中的任何類型錯誤,並透過執行您的測試套件來驗證。
升級您的 Prisma Schema
- 仔細瀏覽變更清單,並檢查您是否受到重大變更的影響。
- 檢閱 Prisma schema 驗證錯誤(透過
npx prisma validate
,或透過 Prisma VS Code 擴充功能)。- 如果您沒有驗證錯誤,請繼續步驟 3。
- 如果您有驗證錯誤
- 嘗試將驗證錯誤對應到以下清單中的變更,以了解哪個變更導致 Prisma schema 無效,並閱讀連結的升級說明。它可能僅來自
- 1:1 關係的明確唯一約束
- 移除對隱式多對多關係使用
references
的支援 - 對 MySQL 和 MongoDB 的一對一和一對多關係中的
references
引數強制執行參照欄位的唯一性 - 移除未記載的
type
別名支援 - 移除 SQLite URL 的
sqlite
協定 - 更好的字串文字語法
- 嘗試將驗證錯誤對應到以下清單中的變更,以了解哪個變更導致 Prisma schema 無效,並閱讀連結的升級說明。它可能僅來自
- 重複直到您的 Prisma schema 有效為止。
- 執行
npx prisma db pull
以將 Prisma schema 升級到所有新功能(例如extendedIndexes
)。 - 檢閱 Prisma schema 的變更並驗證有效性。
- 繼續 Prisma Client 步驟。
升級您對 Prisma Client 的使用
- 仔細瀏覽變更清單,以了解您是否受到重大變更的影響。
- 如果是,請閱讀詳細的升級說明。
- 如果否,請繼續步驟 2。
- Prisma Client 中的某些 API 變更會影響執行階段行為,因此請執行您的測試套件。
享受 Prisma ORM 4!
一般變更
本節包含影響 Prisma Schema 和 Prisma Client 的變更。
Node.js 最低版本變更
從 Prisma ORM 4.0.0 版本開始,我們支援的 Node.js 最低版本為 14.17.x。如果您使用較早版本的 Node.js,則需要更新它。
請參閱我們的系統需求,以了解所有最低版本需求。
Schema 變更
本節包含影響 Prisma Schema 的變更。
索引配置
在 Prisma ORM 4 中,extendedIndexes
預覽功能現在將全面推出。這包括以下索引配置選項
- MySQL 的索引、唯一約束和主鍵約束的長度配置(在 3.5.0 和更高版本中為預覽版)
- 索引、唯一約束和主鍵約束的排序順序配置(在 3.5.0 和更高版本中為預覽版)
- PostgreSQL 的新索引類型:Hash(在 3.6.0 和更高版本中為預覽版)和 GIN、GiST、SP-GiST 和 BRIN(在 3.14.0 和更高版本中為預覽版)
- SQL Server 的索引叢集(在 3.13.0 和更高版本中為預覽版)
請參閱我們關於索引配置的文件,以了解這些功能的更多詳細資訊。
升級路徑
如果您先前在資料庫層級配置這些屬性,則這些都可能是重大變更。在這種情況下,您需要
- 依照這些說明升級到新的 Prisma ORM 4 套件
- 之後執行
npx prisma db pull
以檢索索引和約束的任何現有配置。這需要在執行任何npx prisma db push
或npx prisma migrate dev
命令之前完成,否則您可能會遺失在資料庫中定義但先前未在 Prisma schema 中表示的任何配置。
如需更多詳細資訊,請參閱我們索引配置文件的從先前版本升級章節。
純量列表預設值
對於支援純量列表的資料庫連接器(PostgreSQL、CockroachDB 和 MongoDB),Prisma ORM 4 引入了在您的 Prisma schema 中使用 @default
屬性設定預設值的功能
- 關聯式資料庫
- MongoDB
model User {
id Int @id @default(autoincrement())
posts Post[]
favoriteColors String[] @default(["red", "yellow", "purple"])
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
posts Post[]
favoriteColors String[] @default(["red", "yellow", "purple"])
}
升級路徑
如果您先前在資料庫層級為純量列表定義了預設值,則這是一個重大變更。在這種情況下,您需要
- 依照這些說明升級到新的 Prisma ORM 4 套件
- 之後執行
npx prisma db pull
以檢索索引和約束的任何現有配置。這需要在執行任何npx prisma db push
或npx prisma migrate dev
命令之前完成,否則您將遺失在資料庫中定義但先前未在 Prisma schema 中表示的任何預設值。
一對一關係的明確 @unique
約束
在 Prisma ORM 4 中使用一對一關係時,您需要在關係純量欄位中明確新增 @unique
屬性。例如,對於 User
和 Profile
模型之間的一對一關係,您需要在 profileId
欄位中新增 @unique
屬性
- 關聯式資料庫
- MongoDB
model User {
id Int @id @default(autoincrement())
profile Profile? @relation(fields: [profileId], references: [id])
profileId Int? @unique // <-- include this explicitly
}
model Profile {
id Int @id @default(autoincrement())
user User?
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
profile Profile? @relation(fields: [profileId], references: [id])
profileId String? @unique @db.ObjectId // <-- include this explicitly
}
model Profile {
id String @id @default(auto()) @map("_id") @db.ObjectId
user User?
}
升級路徑
升級到 Prisma ORM 4 後,任何在關係純量上沒有 @unique
屬性的一對一關係都會觸發驗證錯誤。若要升級,您需要
-
依照這些說明升級到新的 Prisma ORM 4 套件
-
透過在您的資料模型中新增明確的
@unique
或@id
屬性,手動修正 Prisma schema 中的驗證錯誤。 -
對於 MongoDB,使用
prisma db push
將變更推送至您的資料庫;對於 MySQL,使用prisma migrate dev
。
強制對一對一和一對多關係使用 @unique
或 @id
屬性(MySQL 和 MongoDB)
當您在 Prisma ORM 4 中使用一對一和一對多關係時,您需要在關係欄位上使用 @unique
屬性,以保證關係的單數側只有一個記錄。現在針對 MySQL 和 MongoDB 強制執行此操作,使其與其他連接器一致。遺失的 @unique
屬性現在將觸發驗證錯誤。
在以下 User
和 Post
模型之間的一對多關係範例中,@unique
屬性必須新增至 email
欄位
- 關聯式資料庫
- MongoDB
model User {
id Int @id @default(autoincrement())
email String @unique // <-- we enforce this attribute
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
authorEmail String
author User @relation(fields: [authorEmail], references: [email])
}
model User {
id Int @id @default(auto()) @map("_id") @db.ObjectId
email String @unique // <-- we enforce this attribute
posts Post[]
}
model Post {
id Int @id @default(auto()) @map("_id") @db.ObjectId
authorEmail String
author User @relation(fields: [authorEmail], references: [email])
}
在以下 User
和 Profile
模型之間的一對一關係範例中,@unique
屬性必須新增至 email
欄位
- 關聯式資料庫
- MongoDB
model User {
id Int @id @default(autoincrement())
email String @unique // <- we enforce this unique attribute
profile Profile @relation(fields: [profileId], references: [id])
profileId Int
}
model Profile {
id Int @id @default(autoincrement())
userEmail String? @unique
user User?
}
model User {
id Int @id @default(auto()) @map("_id") @db.ObjectId
email String @unique // <- we enforce this unique attribute
profile Profile @relation(fields: [profileId], references: [id])
profileId Int @db.ObjectId
}
model Profile {
id Int @id @default(auto()) @map("_id") @db.ObjectId
userEmail String? @unique
user User? @relation(fields: [userEmail], references: [email])
}
升級路徑
升級到 Prisma ORM 4 後,任何在關係欄位上沒有 @unique
或 @id
屬性的一對一或一對多關係都會觸發驗證錯誤。若要升級,您需要
- 依照這些說明升級到新的 Prisma ORM 4 套件
- 手動修正 Prisma schema 中的驗證錯誤。或者,如果您有最新的即時資料庫,執行
npx prisma db pull
將自動新增@unique
屬性。
不允許隱式多對多關係的 references
語法
當在 Prisma ORM 4 中使用隱式多對多關係時,您將無法再使用 references
引數,該引數先前是可選的。例如,以下關係現在將觸發驗證錯誤
model Post {
id Int @id @default(autoincrement())
categories Category[] @relation("my-relation", references: [id]) // <-- validation error
}
model Category {
id Int @id @default(autoincrement())
posts Post[] @relation("my-relation", references: [id]) // <-- validation error
}
相反地,您可以寫成
model Post {
id Int @id @default(autoincrement())
categories Category[] @relation("my-relation")
}
model Category {
id Int @id @default(autoincrement())
posts Post[] @relation("my-relation")
}
這是因為 references
的唯一有效值是 id
,因此移除此引數可以更清楚地了解哪些可以變更,哪些不能變更。
升級路徑
升級到 Prisma ORM 4 後,任何具有 references
引數的隱式多對多關係都會觸發驗證錯誤。若要升級,您需要
- 依照這些說明升級到新的 Prisma ORM 4 套件
- 手動修正 Prisma schema 中的驗證錯誤。或者,如果您有最新的即時資料庫,執行
npx prisma db pull
將自動移除references
引數。
更好的字串文字語法
您的 Prisma Schema 中的字串文字現在需要遵循與 JSON 中的字串相同的規則。這主要變更了一些特殊字元的逸出。更多詳細資訊可以在JSON 規格或JSON 網站上找到。
升級路徑
對於某些現有的 schema,這是一個重大變更。升級到 Prisma ORM 4 後,不正確逸出的字元將觸發驗證錯誤。若要升級,您需要
- 依照這些說明升級到新的 Prisma ORM 4 套件
- 手動修正 Prisma schema 中的驗證錯誤。
Client 變更
本節包含影響 Prisma Client 的變更。
Raw 查詢類型映射:純量值現在反序列化為其正確的 JavaScript 類型
在 3.14.x 和 3.15.x 版本中,raw 查詢類型映射透過預覽功能 improvedQueryRaw
提供。在 4.0.0 版本中,我們已將 raw 查詢類型映射全面推出。您不需要在 4.0.0 和更高版本中使用 improvedQueryRaw
即可獲得此功能。
Raw 查詢現在會將純量值反序列化為其對應的 JavaScript 類型。請注意,Prisma ORM 從值本身而不是從 Prisma Schema 類型推斷類型。
查詢和回應範例
const res =
await prisma.$queryRaw`SELECT bigint, bytes, decimal, date FROM "Table";`
console.log(res) // [{ bigint: BigInt("123"), bytes: Buffer.from([1, 2]), decimal: new Prisma.Decimal("12.34"), date: Date("<some_date>") }]
升級路徑
從 4.0.0 版本開始,queryRaw
或 queryRawUnsafe
傳回的某些資料類型有所不同,如下所示
資料類型 | 4.0.0 版本之前 | 從 4.0.0 版本開始 |
---|---|---|
DateTime | 以 String 傳回 | 以 Date 傳回 |
Numeric | 以 Float 傳回 | 以 Decimal 傳回 |
Bytes | 以 String 傳回 | 以 Buffer 傳回 |
Int64 | 以 Integer 傳回 | 以 BigInt 傳回 |
如果您使用 queryRaw
或 queryRawUnsafe
傳回上述任何資料類型,則您必須變更您的程式碼以處理新的類型。
例如,如果您傳回 DateTime
資料,則您需要考慮以下事項
- 您不再需要手動為傳回的資料實例化
DateTime
物件。 - 如果您的程式碼目前使用傳回的
String
資料,則您現在需要將DateTime
物件轉換為String
。
您必須對上表中的其他資料類型進行等效的程式碼變更。
Raw 查詢映射:PostgreSQL 類型轉換
在 3.14.x 和 3.15.x 版本中,raw 查詢類型映射透過預覽功能 improvedQueryRaw
提供。在 4.0.0 版本中,我們已將 raw 查詢類型映射全面推出。您不需要在 4.0.0 和更高版本中使用 improvedQueryRaw
即可獲得此功能。
在 4.0.0 版本之前,許多 PostgreSQL 類型轉換不起作用。我們已收緊類型強制轉換規則,以便所有類型轉換現在都起作用。因此,某些隱式轉換現在會失敗。
升級路徑
我們建議您重新測試您對 $queryRaw
的使用,以確保您傳遞到 raw 查詢中的類型與 PostgreSQL 預期的類型相符。
例如,在 4.0.0 版本中,以下查詢失敗
await prisma.$queryRaw`select length(${42});`
// ERROR: function length(integer) does not exist
// HINT: No function matches the given name and argument types. You might need to add explicit type casts.
這是因為 PostgreSQL 的 length
函數預期 text
作為輸入。Prisma ORM 過去會靜默地將 42
強制轉換為 text
,但在 4.0.0 版本中不會這樣做。若要修正此問題,請明確地將 42
轉換為 text
,如下所示
await prisma.$queryRaw`select length(${42}::text);`
Raw 查詢映射:PostgreSQL 和 JavaScript 整數
在 3.14.x 和 3.15.x 版本中,raw 查詢類型映射透過預覽功能 improvedQueryRaw
提供。在 4.0.0 版本中,我們已將 raw 查詢類型映射全面推出。您不需要在 4.0.0 和更高版本中使用 improvedQueryRaw
即可獲得此功能。
Prisma ORM 將 JavaScript 整數以 INT8
傳送到 PostgreSQL。這可能會與您的使用者定義函數衝突,這些函數僅接受 INT4
作為輸入。
升級路徑
如果您將 $queryRaw
或參數化的 $queryRawUnsafe
查詢與 PostgreSQL 資料庫一起使用,請執行以下其中一項操作
- 將您的使用者定義函數中任何整數的輸入類型更新為
INT8
,或 - 將您的查詢參數中的任何整數轉換為
INT4
。
DbNull
、JsonNull
和 AnyNull
現在是物件
JavaScript null
對於 JSON 欄位而言是模糊的,因此 Prisma ORM 使用 DbNull
、JsonNull
和 AnyNull
來區分資料庫 NULL
值和 JSON null
值。在 4.0.0 版本之前,DbNull
、JsonNull
和 AnyNull
是字串常數。從 4.0.0 版本開始,它們是物件。
請參閱依 null 值篩選以取得更多資訊。
升級路徑
-
如果您使用字串文字來處理這些值,則您必須將它們替換為以下具名字常數
DbNull
:替換為Prisma.DbNull
JsonNull
:替換為Prisma.JsonNull
AnyNull
:替換為Prisma.AnyNull
如果您已經使用這些具名字常數,則您無需採取任何動作。
-
如果您現在在將
Prisma.DbNull
作為 JSON 欄位的值傳遞時收到類型錯誤,則這可能表示您的程式碼中存在錯誤,而我們的類型在 4.0.0 版本之前未捕獲該錯誤。您嘗試儲存DbNull
的欄位可能在您的 schema 中不可為 null。因此,字串文字DbNull
被儲存在資料庫中,而不是NULL
。 -
當您將
Prisma.DbNull
、Prisma.JsonNull
或Prisma.AnyNull
與 MongoDB 一起使用時,您現在可能會遇到類型錯誤或執行階段驗證錯誤。這從來都不是有效的,但在 Prisma ORM 4 之前被靜默接受。您需要檢閱您的資料並將這些欄位變更為null
。 -
如果您將動態 JSON 傳遞到 Prisma Client 中的 JSON 欄位(例如
prisma.findMany({where: { jsonColumn: someJson } })
),則您必須檢查someJson
是否不能是字串 "DBNull"、"JsonNull" 或 "AnyNull"。如果它是這些值中的任何一個,則查詢將在 4.0.0 版本中傳回不同的結果。
MongoDB 中複合類型上的預設欄位
從 4.0.0 版本開始,如果您在所有以下條件都為真時對複合類型執行資料庫讀取,則 Prisma Client 會將預設值插入到結果中。
條件
- 複合類型上的欄位是必要的,並且
- 此欄位具有預設值,並且
- 此欄位不存在於傳回的文件或文件中。
此行為現在與模型欄位的行為一致。
若要了解更多資訊,請參閱複合類型上必要欄位的預設值。
升級路徑
如果您目前依賴 null
的傳回值,則您需要重構您的程式碼以處理 Prisma ORM 4 中現在傳回的預設值。
SQLite 中大數值的捨入錯誤
SQLite 是一個鬆散類型的資料庫。如果您的 schema 具有類型為 Int
的欄位,則 Prisma ORM 會阻止您插入大於整數的值。但是,沒有任何東西阻止資料庫直接接受更大的數字。這些手動插入的大數字在查詢時會導致捨入錯誤。
為了避免此問題,Prisma ORM 4.0.0 和更高版本會在數字離開資料庫時檢查數字,以驗證它們是否在整數的邊界內。如果數字不符合,則 Prisma ORM 會拋出 P2023 錯誤,例如
Inconsistent column data: Conversion failed:
Value 9223372036854775807 does not fit in an INT column,
try migrating the 'int' column type to BIGINT
升級路徑
如果您將 Prisma ORM 與 SQLite 結合使用,則您需要找到任何查詢 Int
欄位的程式碼,並確保它處理可能傳回的任何 P2023 錯誤。
Prisma ORM 不再將 Prisma.dmmf.schema
匯出到產生的 Prisma Client 中
從 4.0.0 版本開始,Prisma ORM 不再將 Prisma.dmmf.schema
匯出到產生的 Prisma Client 中。這使得產生的 Prisma Client 效率更高,並且還避免了 Jest 的一些記憶體洩漏。
注意
- 此變更不會影響 Prisma ORM 傳遞給產生器的 DMMF。
- 您可以使用來自
@prisma/internals
的getDmmf()
來存取 schema 屬性。 - 我們仍然將
Prisma.dmmf.datamodel
匯出到產生的 Prisma Client 中。
將 prisma
和 @prisma/client
套件升級到版本 4
若要從較早版本升級到 Prisma ORM 4,您需要更新 prisma
和 @prisma/client
套件。prisma
和 @prisma/client
套件都以插入符號 ^
安裝在其版本號碼中。這允許升級到新的次要版本,但不允許升級到主要版本,以防止重大變更。
若要忽略插入符號 ^
並跨主要版本升級,您可以在使用 npm
或 yarn
升級時使用 @4
標籤
在升級之前,請檢查每個重大變更,以了解升級可能如何影響您的應用程式。
- npm
- yarn
npm install prisma@4 @prisma/client@4
yarn up prisma@4 @prisma/client@4
影片指南
如需升級過程的影片逐步解說和升級情境範例,請參閱我們關於升級到 Prisma ORM 4 的錄製直播