Skip to main content

自定义模型和字段名称

Prisma 客户端 API 是根据 Prisma 架构 中的模型生成的。模型通常是数据库表的 1:1 映射。

¥The Prisma Client API is generated based on the models in your Prisma schema. Models are typically 1:1 mappings of your database tables.

在某些情况下,特别是在使用 introspection 时,将数据库表和列的命名与 Prisma 客户端 API 中使用的名称解耦可能会很有用。这可以通过 Prisma 架构中的 @map@@map 属性来完成。

¥In some cases, especially when using introspection, it might be useful to decouple the naming of database tables and columns from the names that are used in your Prisma Client API. This can be done via the @map and @@map attributes in your Prisma schema.

你可以使用 @map@@map 分别重命名 MongoDB 字段和集合。本页使用关系数据库示例。

¥You can use @map and @@map to rename MongoDB fields and collections respectively. This page uses a relational database example.

示例:关系型数据库

¥Example: Relational database

假设你有一个类似于以下内容的 PostgreSQL 关系数据库架构:

¥Assume you have a PostgreSQL relational database schema looking similar to this:

CREATE TABLE users (
user_id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(256),
email VARCHAR(256) UNIQUE NOT NULL
);
CREATE TABLE posts (
post_id SERIAL PRIMARY KEY NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
title VARCHAR(256) NOT NULL,
content TEXT,
author_id INTEGER REFERENCES users(user_id)
);
CREATE TABLE profiles (
profile_id SERIAL PRIMARY KEY NOT NULL,
bio TEXT,
user_id INTEGER NOT NULL UNIQUE REFERENCES users(user_id)
);
CREATE TABLE categories (
category_id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(256)
);
CREATE TABLE post_in_categories (
post_id INTEGER NOT NULL REFERENCES posts(post_id),
category_id INTEGER NOT NULL REFERENCES categories(category_id)
);
CREATE UNIQUE INDEX post_id_category_id_unique ON post_in_categories(post_id int4_ops,category_id int4_ops);

当使用该模式自省数据库时,你将得到一个与此类似的 Prisma 模式:

¥When introspecting a database with that schema, you'll get a Prisma schema looking similar to this:

model categories {
category_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
post_in_categories post_in_categories[]
}

model post_in_categories {
post_id Int
category_id Int
categories categories @relation(fields: [category_id], references: [category_id], onDelete: NoAction, onUpdate: NoAction)
posts posts @relation(fields: [post_id], references: [post_id], onDelete: NoAction, onUpdate: NoAction)

@@unique([post_id, category_id], map: "post_id_category_id_unique")
}

model posts {
post_id Int @id @default(autoincrement())
created_at DateTime? @default(now()) @db.Timestamptz(6)
title String @db.VarChar(256)
content String?
author_id Int?
users users? @relation(fields: [author_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
post_in_categories post_in_categories[]
}

model profiles {
profile_id Int @id @default(autoincrement())
bio String?
user_id Int @unique
users users @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
}

model users {
user_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
email String @unique @db.VarChar(256)
posts posts[]
profiles profiles?
}

生成 Prisma Client API 时,有几个具有此 Prisma 架构的 "issues":

¥There are a few "issues" with this Prisma schema when the Prisma Client API is generated:

遵守 Prisma ORM 的命名约定

¥Adhering to Prisma ORM's naming conventions

Prisma ORM 有 命名约定 的驼峰式外壳并使用单数形式的 Prisma 模型。如果不满足这些命名约定,Prisma 模式可能会变得更难以解释,并且生成的 Prisma 客户端 API 会感觉不太自然。考虑以下生成的模型:

¥Prisma ORM has a naming convention of camelCasing and using the singular form for Prisma models. If these naming conventions are not met, the Prisma schema can become harder to interpret and the generated Prisma Client API will feel less natural. Consider the following, generated model:

model users {
user_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
email String @unique @db.VarChar(256)
posts posts[]
profiles profiles?
}

虽然 profiles 指的是 1:1 关系,但其类型目前被称为复数形式的 profiles,表明这种关系中可能存在很多 profiles。根据 Prisma ORM 约定,模型和字段的理想命名如下:

¥Although profiles refers to a 1:1 relation, its type is currently called profiles in plural, suggesting that there might be many profiles in this relation. With Prisma ORM conventions, the models and fields were ideally named as follows:

model User {
user_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
email String @unique @db.VarChar(256)
posts Post[]
profile Profile?
}

由于这些字段是 "Prisma ORM 级别" 关系字段 未显示,因此你可以在 Prisma 架构中手动重命名它们。

¥Because these fields are "Prisma ORM-level" relation fields that do not manifest you can manually rename them in your Prisma schema.

带注释的关系字段的命名

¥Naming of annotated relation fields

外键在 Prisma 模式中表示为 带注释的关系字段 及其对应关系标量字段的组合。以下是当前 SQL 模式中所有关系的表示方式:

¥Foreign keys are represented as a combination of a annotated relation fields and its corresponding relation scalar field in the Prisma schema. Here's how all the relations from the SQL schema are currently represented:

model categories {
category_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
post_in_categories post_in_categories[] // virtual relation field
}

model post_in_categories {
post_id Int // relation scalar field
category_id Int // relation scalar field
categories categories @relation(fields: [category_id], references: [category_id], onDelete: NoAction, onUpdate: NoAction) // virtual relation field
posts posts @relation(fields: [post_id], references: [post_id], onDelete: NoAction, onUpdate: NoAction)

@@unique([post_id, category_id], map: "post_id_category_id_unique")
}

model posts {
post_id Int @id @default(autoincrement())
created_at DateTime? @default(now()) @db.Timestamptz(6)
title String @db.VarChar(256)
content String?
author_id Int?
users users? @relation(fields: [author_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
post_in_categories post_in_categories[]
}

model profiles {
profile_id Int @id @default(autoincrement())
bio String?
user_id Int @unique
users users @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
}

model users {
user_id Int @id @default(autoincrement())
name String? @db.VarChar(256)
email String @unique @db.VarChar(256)
posts posts[]
profiles profiles?
}

使用 @map@@map 重命名 Prisma 客户端 API 中的字段和模型

¥Using @map and @@map to rename fields and models in the Prisma Client API

你可以使用 @map@@map 属性将 Prisma Client 中使用的 "rename" 字段和模型映射到数据库中的 "original" 名称。对于上面的示例,你可以例如 按如下方式注释你的模型。

¥You can "rename" fields and models that are used in Prisma Client by mapping them to the "original" names in the database using the @map and @@map attributes. For the example above, you could e.g. annotate your models as follows.

使用 prisma db pull 自省数据库后,你可以手动调整生成的 Prisma 架构,如下所示:

¥After you introspected your database with prisma db pull, you can manually adjust the resulting Prisma schema as follows:

model Category {
id Int @id @default(autoincrement()) @map("category_id")
name String? @db.VarChar(256)
post_in_categories PostInCategories[]

@@map("categories")
}

model PostInCategories {
post_id Int
category_id Int
categories Category @relation(fields: [category_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
posts Post @relation(fields: [post_id], references: [id], onDelete: NoAction, onUpdate: NoAction)

@@unique([post_id, category_id], map: "post_id_category_id_unique")
@@map("post_in_categories")
}

model Post {
id Int @id @default(autoincrement()) @map("post_id")
created_at DateTime? @default(now()) @db.Timestamptz(6)
title String @db.VarChar(256)
content String?
author_id Int?
users User? @relation(fields: [author_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
post_in_categories PostInCategories[]

@@map("posts")
}

model Profile {
id Int @id @default(autoincrement()) @map("profile_id")
bio String?
user_id Int @unique
users User @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction)

@@map("profiles")
}

model User {
id Int @id @default(autoincrement()) @map("user_id")
name String? @db.VarChar(256)
email String @unique @db.VarChar(256)
posts Post[]
profiles Profile?

@@map("users")
}

通过这些更改,你现在遵守 Prisma ORM 的命名约定,并且生成的 Prisma Client API 感觉更加 "natural":

¥With these changes, you're now adhering to Prisma ORM's naming conventions and the generated Prisma Client API feels more "natural":

// Nested writes
const profile = await prisma.profile.create({
data: {
bio: 'Hello World',
users: {
create: {
name: 'Alice',
email: 'alice@prisma.io',
},
},
},
})

// Fluent API
const userByProfile = await prisma.profile
.findUnique({
where: { id: 1 },
})
.users()
信息

prisma db pull 在重新检查数据库时保留你在 Prisma 模式中通过 @map@@map 定义的自定义名称。

¥prisma db pull preserves the custom names you defined via @map and @@map in your Prisma schema on re-introspecting your database.

重命名关系字段

¥Renaming relation fields

Prisma ORM 级别 关系字段(有时称为 "虚拟关系字段")仅存在于 Prisma 模式中,但实际上并不体现在底层数据库中。因此,你可以随意命名这些字段。

¥Prisma ORM-level relation fields (sometimes referred to as "virtual relation fields") only exist in the Prisma schema, but do not actually manifest in the underlying database. You can therefore name these fields whatever you want.

考虑以下 SQL 数据库中的不明确关系示例:

¥Consider the following example of an ambiguous relation in a SQL database:

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 的自省将输出以下 Prisma 模式:

¥Prisma ORM's introspection will output the following Prisma schema:

model Post {
id Int @id @default(autoincrement())
author Int
favoritedBy Int?
User_Post_authorToUser User @relation("Post_authorToUser", fields: [author], references: [id], onDelete: NoAction, onUpdate: NoAction)
User_Post_favoritedByToUser User? @relation("Post_favoritedByToUser", fields: [favoritedBy], references: [id], onDelete: NoAction, onUpdate: NoAction)
}

model User {
id Int @id @default(autoincrement())
Post_Post_authorToUser Post[] @relation("Post_authorToUser")
Post_Post_favoritedByToUser Post[] @relation("Post_favoritedByToUser")
}

由于虚拟关系字段 Post_Post_authorToUserPost_Post_favoritedByToUser 的名称是基于生成的关系名称,因此它们在 Prisma Client API 中看起来不太友好。在这种情况下,你可以重命名关系字段。例如:

¥Because the names of the virtual relation fields Post_Post_authorToUser and Post_Post_favoritedByToUser are based on the generated relation names, they don't look very friendly in the Prisma Client API. In that case, you can rename the relation fields. For example:

model Post {
id Int @id @default(autoincrement())
author Int
favoritedBy Int?
User_Post_authorToUser User @relation("Post_authorToUser", fields: [author], references: [id], onDelete: NoAction, onUpdate: NoAction)
User_Post_favoritedByToUser User? @relation("Post_favoritedByToUser", fields: [favoritedBy], references: [id], onDelete: NoAction, onUpdate: NoAction)
}

model User {
id Int @id @default(autoincrement())
writtenPosts Post[] @relation("Post_authorToUser")
favoritedPosts Post[] @relation("Post_favoritedByToUser")
}
信息

prisma db pull 在重新检查数据库时保留 Prisma 架构中定义的自定义关系字段。

¥prisma db pull preserves custom relation fields defined in your Prisma schema on re-introspecting your database.