跳到主要内容

数据库映射

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',
},
},
})