跳到主要內容

資料庫對映

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

對映集合/表名和欄位/列名

有時,用於描述資料庫中實體的名稱可能與您在生成的 API 中偏好的名稱不匹配。在 Prisma schema 中對映名稱使您無需更改底層資料庫名稱即可影響 Client API 中的命名。

例如,在資料庫中命名錶/集合的常見方法是使用複數形式和 snake_case(蛇形命名法)。但是,我們推薦不同的命名約定(單數形式,PascalCase 帕斯卡命名法)

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

對映集合/表名

例如,當您內省一個名為 comments 的資料庫表時,生成的 Prisma 模型將如下所示

model comments {
// Fields
}

但是,您仍然可以透過使用@@map 屬性,將 Comment 作為模型名稱(例如,為了遵循命名約定),而無需重新命名資料庫中底層的 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 及更高版本 中可用。)

內省資料庫時,map 引數僅當名稱與 Prisma ORM 的索引和約束預設命名約定不同時才會在 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 將根據預設命名約定生成索引和約束名稱。

如果您內省一個數據庫,索引和約束的名稱將被新增到您的 schema 中,除非它們遵循 Prisma ORM 的命名約定。如果遵循,則不渲染這些名稱以保持 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',
},
},
})
© . This site is unofficial and not affiliated with Prisma Data, Inc.