跳到主要內容

資料庫映射

Prisma schema 包含允許您定義特定資料庫物件名稱的機制。您可以

映射集合/表格和欄位/欄位名稱

有時,用於描述資料庫中實體的名稱可能與您在產生的 API 中偏好的名稱不符。在 Prisma schema 中映射名稱可讓您影響 Client API 中的命名,而無需變更底層資料庫名稱。

例如,在資料庫中命名表格/集合的常見方法是使用複數形式和 snake_case 標記法。但是,我們建議使用不同的 命名慣例(單數形式,PascalCase)

@map@@map 允許您透過將模型和欄位名稱與底層資料庫中的表格和欄位名稱解耦,來 調整 Prisma Client API 的形狀

映射集合 / 表格名稱

例如,當您 內省 具有名為 comments 的表格的資料庫時,產生的 Prisma 模型將如下所示

model comments {
// Fields
}

但是,您仍然可以選擇 Comment 作為模型的名稱(例如,為了遵循命名慣例),而無需透過使用 @@map 屬性來重新命名資料庫中底層的 comments 表格

model Comment {
// Fields

@@map("comments")
}

透過此修改後的模型定義,Prisma Client 會自動將 Comment 模型映射到底層資料庫中的 comments 表格。

映射欄位 / 欄位名稱

您也可以 @map 欄位/欄位名稱

model Comment {
content String @map("comment_text")
email String @map("commenter_email")
type Enum @map("comment_type")

@@map("comments")
}

這樣,comment_text 欄位在 Prisma Client API 中無法透過 prisma.comment.comment_text 存取,但可以透過 prisma.comment.content 存取。

映射列舉名稱和值

您也可以 @map 列舉值,或 @@map 列舉

enum Type {
Blog,
Twitter @map("comment_twitter")

@@map("comment_source_enum")
}

約束和索引名稱

您可以選擇性地使用 map 參數,在 Prisma schema 中為屬性 @id@@id@unique@@unique@@index@relation 明確定義底層約束和索引名稱。(這在 Prisma ORM 版本 2.29.0 及更高版本中提供。)

當內省資料庫時,如果名稱與 Prisma ORM 的 索引和約束的預設命名慣例不同,則 map 參數將在 schema 中呈現。

危險

如果您在早於 2.29.0 的版本中使用 Prisma Migrate,並且想要在升級到較新版本後維護現有的約束和索引名稱,請勿立即執行 prisma migrateprisma db push。這將變更任何不遵循 Prisma ORM 慣例的底層約束名稱。請遵循 允許您維護現有約束和索引名稱的升級路徑

具名約束的使用案例

明確命名的約束的一些使用案例包括

  • 公司政策
  • 其他工具的慣例

Prisma ORM 的索引和約束的預設命名慣例

選擇 Prisma ORM 命名慣例是為了與 PostgreSQL 對齊,因為它是確定性的。這也有助於最大化不需要呈現名稱的次數,因為許多現有的資料庫已經與該慣例對齊。

當產生預設索引和約束名稱時,Prisma ORM 始終使用實體的資料庫名稱。如果模型透過 @@map@map 在資料模型中重新映射到不同的名稱,則預設名稱產生仍將採用資料庫中表格的名稱作為輸入。欄位和欄位也是如此。

實體慣例範例
主鍵{tablename}_pkeyUser_pkey
唯一約束{tablename}_{column_names}_keyUser_firstName_last_Name_key
非唯一索引{tablename}_{column_names}_idxUser_age_idx
外鍵{tablename}_{column_names}_fkeyUser_childName_fkey

由於大多數資料庫對實體名稱的長度有限制,因此如有必要,將修剪名稱以不違反資料庫限制。我們將根據需要縮短 _suffix 之前的部分,以使完整名稱最多為允許的最大長度。

使用預設約束名稱

當未透過 map 參數提供明確的名稱時,Prisma ORM 將遵循 預設命名慣例 產生索引和約束名稱。

如果您內省資料庫,除非索引和約束的名稱遵循 Prisma ORM 的命名慣例,否則它們的名稱將新增到您的 schema 中。如果它們遵循,則不會呈現名稱以保持 schema 更具可讀性。當您遷移這樣的 schema 時,Prisma 將推斷預設名稱並將其持久保存在資料庫中。

範例

以下 schema 定義了三個約束(@id@unique@relation)和一個索引(@@index

model User {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])

@@index([title, authorName])
}

由於未透過 map 參數提供明確的名稱,Prisma 將假定它們遵循我們的預設命名慣例。

下表列出了底層資料庫中每個約束和索引的名稱

約束或索引遵循慣例底層約束或索引名稱
@id (在 User > id 欄位上)User_pk
@@index (在 Post 上)Post_title_authorName_idx
@id (在 Post > id 欄位上)Post_pk
@relation (在 Post > author 上)Post_authorName_fkey

使用自訂約束 / 索引名稱

您可以使用 map 參數在底層資料庫中定義自訂約束和索引名稱

範例

以下範例將自訂名稱新增到一個 @id@@index

model User {
id Int @id(map: "Custom_Primary_Key_Constraint_Name") @default(autoincrement())
name String @unique
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])

@@index([title, authorName], map: "My_Custom_Index_Name")
}

下表列出了底層資料庫中每個約束和索引的名稱

約束或索引遵循慣例底層約束或索引名稱
@id (在 User > id 欄位上)Custom_Primary_Key_Constraint_Name
@@index (在 Post 上)My_Custom_Index_Name
@id (在 Post > id 欄位上)Post_pk
@relation (在 Post > author 上)Post_authorName_fkey

除了 map 之外,@@id@@unique 屬性還採用可選的 name 參數,讓您可以自訂 Prisma Client API。

在像這樣的模型上

model User {
firstName String
lastName String

@@id([firstName, lastName])
}

用於在該主鍵上進行選擇的預設 API 使用欄位的產生組合

const user = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})

指定 @@id([firstName, lastName], name: "fullName") 將把 Prisma Client API 變更為這樣

const user = await prisma.user.findUnique({
where: {
fullName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})