內省
您可以使用 Prisma CLI 內省您的資料庫,以便在您的 Prisma Schema 中產生 資料模型。需要資料模型才能產生 Prisma Client。
當將 Prisma ORM 新增至現有專案時,內省通常用於產生資料模型的初始版本。
但是,它也可以在應用程式中重複使用。當您不使用 Prisma Migrate,而是使用純 SQL 或其他遷移工具執行 Schema 遷移時,這是最常見的情況。在這種情況下,您也需要重新內省您的資料庫,然後重新產生 Prisma Client,以反映 Prisma Client API 中的 Schema 變更。
內省有什麼作用?
內省有一個主要功能:使用反映目前資料庫 Schema 的資料模型來填充您的 Prisma Schema。
以下是其在 SQL 資料庫上的主要功能概述
- 將資料庫中的表格對應到 Prisma 模型
- 將資料庫中的欄位對應到 Prisma 模型的欄位
- 將資料庫中的索引對應到 Prisma Schema 中的索引
- 將資料庫約束對應到 Prisma Schema 中的屬性或類型修飾符
在 MongoDB 上,主要功能如下
- 將資料庫中的集合對應到 Prisma 模型。由於 MongoDB 中的集合沒有預定義的結構,Prisma ORM 會取樣集合中的文件,並據此推導模型結構(即,它將文件的欄位對應到 Prisma 模型的欄位)。如果在集合中偵測到嵌入式類型,這些將會對應到 Prisma Schema 中的複合類型。
- 如果集合包含至少一個文件,其中包含索引中包含的欄位,則將資料庫中的索引對應到 Prisma Schema 中的索引
您可以造訪資料來源連接器的相關文件頁面,以深入了解 Prisma ORM 如何將類型從資料庫對應到 Prisma Schema 中可用的類型
prisma db pull
命令
您可以使用 Prisma CLI 的 prisma db pull
命令內省您的資料庫。請注意,使用此命令需要您的連線 URL 設定在您的 Prisma Schema datasource
中。
以下是 prisma db pull
在內部執行的步驟的高階概述
- 從 Prisma Schema 中的
datasource
配置讀取連線 URL - 開啟與資料庫的連線
- 內省資料庫 Schema(即讀取表格、欄位和其他結構...)
- 將資料庫 Schema 轉換為 Prisma Schema 資料模型
- 將資料模型寫入 Prisma Schema 或更新現有 Schema
內省工作流程
不使用 Prisma Migrate,而是使用純 SQL 或其他遷移工具的專案的典型工作流程如下
- 變更資料庫 Schema(例如,使用純 SQL)
- 執行
prisma db pull
以更新 Prisma Schema - 執行
prisma generate
以更新 Prisma Client - 在您的應用程式中使用更新後的 Prisma Client
請注意,隨著您發展應用程式,此流程可以無限次重複。
規則與慣例
Prisma ORM 採用許多慣例,將資料庫 Schema 轉換為 Prisma Schema 中的資料模型
模型、欄位和列舉名稱
欄位、模型和列舉名稱(識別符)必須以字母開頭,並且通常只能包含底線、字母和數字。您可以在相關文件頁面上找到每個識別符的命名規則和慣例
識別符的一般規則是它們需要遵守此正規表示式
[A-Za-z][A-Za-z0-9_]*
清理無效字元
在內省期間會清理無效字元
- 如果它們出現在識別符中字母之前,則會被刪除。
- 如果它們出現在第一個字母之後,則會被底線取代。
此外,轉換後的名稱會使用 @map
或 @@map
對應到資料庫,以保留原始名稱。
將下表視為範例
CREATE TABLE "42User" (
_id SERIAL PRIMARY KEY,
_name VARCHAR(255),
two$two INTEGER
);
由於表格名稱中的前導 42
以及欄位上的前導底線和 $
在 Prisma ORM 中是被禁止的,因此內省會新增 @map
和 @@map
屬性,使這些名稱符合 Prisma ORM 的命名慣例
model User {
id Int @id @default(autoincrement()) @map("_id")
name String? @map("_name")
two_two Int? @map("two$two")
@@map("42User")
}
清理後重複的識別符
如果清理導致重複的識別符,則不會立即進行錯誤處理。您稍後會收到錯誤,並且可以手動修正。
考慮以下兩個表格的情況
CREATE TABLE "42User" (
_id SERIAL PRIMARY KEY
);
CREATE TABLE "24User" (
_id SERIAL PRIMARY KEY
);
這會導致以下內省結果
model User {
id Int @id @default(autoincrement()) @map("_id")
@@map("42User")
}
model User {
id Int @id @default(autoincrement()) @map("_id")
@@map("24User")
}
嘗試使用 prisma generate
產生您的 Prisma Client,您會收到以下錯誤
npx prisma generate
$ npx prisma generate
Error: Schema parsing
error: The model "User" cannot be defined because a model with that name already exists.
--> schema.prisma:17
|
16 | }
17 | model User {
|
Validation Error Count: 1
在這種情況下,您必須手動變更兩個產生的 User
模型之一的名稱,因為 Prisma Schema 中不允許重複的模型名稱。
欄位順序
內省會以與資料庫中對應表格欄位相同的順序,列出模型欄位。
屬性順序
內省會以下列順序新增屬性(此順序會由 prisma format
反映)
- 區塊層級:
@@id
、@@unique
、@@index
、@@map
- 欄位層級:
@id
、@unique
、@default
、@updatedAt
、@map
、@relation
關聯
Prisma ORM 將在您的資料庫表格上定義的外鍵轉換為關聯。
一對一關聯
當表格上的外鍵具有 UNIQUE
約束時,Prisma ORM 會將一對一關聯新增至您的資料模型,例如
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Profile" (
id SERIAL PRIMARY KEY,
"user" integer NOT NULL UNIQUE,
FOREIGN KEY ("user") REFERENCES "User"(id)
);
Prisma ORM 將其轉換為以下資料模型
model User {
id Int @id @default(autoincrement())
Profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
user Int @unique
User User @relation(fields: [user], references: [id])
}
一對多關聯
預設情況下,Prisma ORM 會為在您的資料庫 Schema 中找到的外鍵,將一對多關聯新增至您的資料模型
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"author" integer NOT NULL,
FOREIGN KEY ("author") REFERENCES "User"(id)
);
這些表格會轉換為以下模型
model User {
id Int @id @default(autoincrement())
Post Post[]
}
model Post {
id Int @id @default(autoincrement())
author Int
User User @relation(fields: [author], references: [id])
}
多對多關聯
Prisma ORM 支援兩種在 Prisma Schema 中定義多對多關聯的方式
如果隱含多對多關聯符合 Prisma ORM 的關聯表格慣例,則會被識別。否則,關聯表格會在 Prisma Schema 中呈現為模型(因此使其成為顯式多對多關聯)。
此主題在關於關聯的文件頁面上有廣泛的介紹。
消除關聯歧義
如果不需要,Prisma ORM 通常會省略 @relation
屬性上的 name
引數。考慮先前章節中的 User
↔ Post
範例。 @relation
屬性僅具有 references
引數,省略了 name
,因為在此案例中不需要它
model Post {
id Int @id @default(autoincrement())
author Int
User User @relation(fields: [author], references: [id])
}
如果在 Post
表格上定義了兩個外鍵,則需要它
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"author" integer NOT NULL,
"favoritedBy" INTEGER,
FOREIGN KEY ("author") REFERENCES "User"(id),
FOREIGN KEY ("favoritedBy") REFERENCES "User"(id)
);
在這種情況下,Prisma ORM 需要使用專用的關聯名稱消除關聯歧義
model Post {
id Int @id @default(autoincrement())
author Int
favoritedBy Int?
User_Post_authorToUser User @relation("Post_authorToUser", fields: [author], references: [id])
User_Post_favoritedByToUser User? @relation("Post_favoritedByToUser", fields: [favoritedBy], references: [id])
}
model User {
id Int @id @default(autoincrement())
Post_Post_authorToUser Post[] @relation("Post_authorToUser")
Post_Post_favoritedByToUser Post[] @relation("Post_favoritedByToUser")
}
請注意,您可以將Prisma-ORM 層級關聯欄位重新命名為您喜歡的任何名稱,使其在產生的 Prisma Client API 中看起來更友善。
使用現有 Schema 進行內省
針對具有現有 Prisma Schema 的關聯式資料庫執行 prisma db pull
,會將對 Schema 進行的手動變更與資料庫中的變更合併。(此功能已在 2.6.0 版本中首次新增。)對於 MongoDB,目前的內省僅適用於初始資料模型執行一次。重複執行它會導致自訂變更遺失,如下列所列。
關聯式資料庫的內省會維護以下手動變更
model
區塊的順序enum
區塊的順序- 註解
@map
和@@map
屬性@updatedAt
@default(cuid())
(cuid()
是 Prisma-ORM 層級函數)@default(uuid())
(uuid()
是 Prisma-ORM 層級函數)- 自訂
@relation
名稱
注意:僅會擷取資料庫層級模型之間的關聯。這表示必須設定外鍵。
Schema 的以下屬性由資料庫決定
model
區塊內欄位的順序enum
區塊內值的順序
注意:所有
enum
區塊都列在model
區塊下方。
強制覆寫
若要覆寫手動變更,並產生完全基於內省資料庫的 Schema,並忽略任何現有的 Prisma Schema,請將 --force
標記新增至 db pull
命令
npx prisma db pull --force
使用案例包括
- 您想要從頭開始使用從底層資料庫產生的 Schema
- 您有一個無效的 Schema,並且必須使用
--force
才能使內省成功
僅內省資料庫 Schema 的子集
Prisma ORM 尚未正式支援僅內省資料庫 Schema 的子集。
但是,您可以透過建立一個新的資料庫使用者來實現此目的,該使用者僅有權存取您想要在 Prisma Schema 中表示的表格,然後使用該使用者執行內省。然後,內省將僅包含新使用者有權存取的表格。
如果您的目標是從Prisma Client 產生中排除某些模型,您可以將 @@ignore
屬性新增至您的 Prisma Schema 中的模型定義。忽略的模型會從產生的 Prisma Client 中排除。
針對不支援的功能的內省警告
Prisma Schema Language (PSL) 可以表達 Prisma ORM 支援的目標資料庫的大多數資料庫功能。但是,Prisma Schema Language 仍然需要表達某些功能和功能。
對於這些功能,Prisma CLI 將顯示偵測到您的資料庫中使用該功能並傳回警告。Prisma CLI 也會在模型和欄位中新增註解,說明這些功能在 Prisma Schema 中正在使用。警告也將包含解決方案建議。
prisma db pull
命令將顯示以下不支援的功能
您可以在 GitHub 上找到我們打算支援的功能列表(標記為 topic:database-functionality
)。
針對不支援的功能的內省警告的變通方案
如果您使用的是關聯式資料庫,並且具有上一節中列出的上述功能之一
- 建立草稿遷移
npx prisma migrate dev --create-only
- 新增 SQL,以新增警告中顯示的功能。
- 將草稿遷移套用至您的資料庫
npx prisma migrate dev