自訂模型與欄位名稱
Prisma Client API 是根據您的 Prisma schema 中的模型所產生。模型通常是資料庫表格的 1:1 對應。
在某些情況下,尤其是在使用內省時,將資料庫表格和資料行的命名與 Prisma Client API 中使用的名稱分離可能會很有用。這可以透過您的 Prisma schema 中的 @map
和 @@map
屬性來完成。
您可以使用 @map
和 @@map
分別重新命名 MongoDB 欄位和集合。此頁面使用關聯式資料庫範例。
範例:關聯式資料庫
假設您有一個 PostgreSQL 關聯式資料庫結構描述,看起來與此類似
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 schema
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 schema 存在一些「問題」
遵守 Prisma ORM 的命名慣例
Prisma ORM 具有 命名慣例,即 Prisma 模型使用駝峰式命名和單數形式。如果未滿足這些命名慣例,Prisma schema 可能會變得更難以理解,且產生的 Prisma Client API 將感覺較不自然。考慮以下產生的模型
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 慣例,模型和欄位的理想命名如下
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 schema 中重新命名它們。
已註解關聯欄位的命名
外鍵在 Prisma schema 中表示為已註解關聯欄位及其對應的關聯純量欄位的組合。以下是目前 SQL schema 中所有關係的表示方式
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 Client API 中重新命名欄位和模型
您可以透過使用 @map
和 @@map
屬性將 Prisma Client 中使用的欄位和模型對應到資料庫中的「原始」名稱,來「重新命名」它們。對於上面的範例,您可以依照以下方式註解您的模型。
在您使用 prisma db pull
內省資料庫之後,您可以手動調整產生的 Prisma schema,如下所示
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 感覺更「自然」
// 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 schema 中的 @map
和 @@map
定義的自訂名稱。
重新命名關聯欄位
Prisma ORM 層級的關聯欄位(有時稱為「虛擬關聯欄位」)僅存在於 Prisma schema 中,但實際上並未在底層資料庫中顯現。因此,您可以隨意命名這些欄位。
考慮以下 SQL 資料庫中不明確關係的範例
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 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_authorToUser
和 Post_Post_favoritedByToUser
的名稱是根據產生的關聯名稱而定,因此它們在 Prisma Client API 中看起來不太友善。在這種情況下,您可以重新命名關聯欄位。例如
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 schema 中定義的自訂關聯欄位。