什麼是內省?
您可以使用 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 命令對資料庫進行內省。請注意,使用此命令需要在 Prisma schema datasource 中設定您的連線 URL。
以下是 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