内省
使用 Prisma ORM 内省你的数据库
为了本指南的目的,我们将使用一个包含三个表的演示 SQL 模式
CREATE TABLE "public"."User" (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE "public"."Post" (
id SERIAL PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL,
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
content TEXT,
published BOOLEAN NOT NULL DEFAULT false,
"authorId" INTEGER NOT NULL,
FOREIGN KEY ("authorId") REFERENCES "public"."User"(id)
);
CREATE TABLE "public"."Profile" (
id SERIAL PRIMARY KEY NOT NULL,
bio TEXT,
"userId" INTEGER UNIQUE NOT NULL,
FOREIGN KEY ("userId") REFERENCES "public"."User"(id)
);
注意:某些字段使用双引号编写,以确保 PostgreSQL 使用正确的 casing。如果不使用双引号,PostgreSQL 会将所有内容读取为小写字符。
展开以查看表的图形化概述
User
列名 | 类型 | 主键 | 外键 | 必需 | 默认 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自增 |
name | VARCHAR(255) | 否 | 否 | 否 | - |
email | VARCHAR(255) | 否 | 否 | ✔️ | - |
Post
列名 | 类型 | 主键 | 外键 | 必需 | 默认 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自增 |
createdAt | TIMESTAMP | 否 | 否 | ✔️ | now() |
title | VARCHAR(255) | 否 | 否 | ✔️ | - |
content | TEXT | 否 | 否 | 否 | - |
published | BOOLEAN | 否 | 否 | ✔️ | false |
authorId | INTEGER | 否 | ✔️ | ✔️ | - |
Profile
列名 | 类型 | 主键 | 外键 | 必需 | 默认 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自增 |
bio | TEXT | 否 | 否 | 否 | - |
userId | INTEGER | 否 | ✔️ | ✔️ | - |
下一步,你将内省你的数据库。内省的结果将是 Prisma 模式中的一个数据模型。
运行以下命令来内省你的数据库
npx prisma db pull
此命令读取在 .env
中定义的 DATABASE_URL
环境变量,并连接到你的数据库。连接建立后,它会内省数据库(即它读取数据库模式)。然后,它将数据库模式从 SQL 转换为 Prisma 模式中的数据模型。
内省完成后,你的 Prisma 模式将被更新
数据模型现在看起来类似于这样(请注意,模型上的字段为了更好的可读性而被重新排序)
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
Post Post[]
Profile Profile?
}
Prisma ORM 的数据模型是你数据库模式的声明式表示,并作为生成的 Prisma Client 库的基础。你的 Prisma Client 实例将公开为这些模型量身定制的查询。
现在,数据模型存在一些小的“问题”
User
关系字段为大写,因此不符合 Prisma 的命名约定。为了表达更多的“语义”,如果这个字段被称为author
以更好地描述User
和Post
之间的关系,那就更好了。User
上的Post
和Profile
关系字段以及Profile
上的User
关系字段均为大写。为了符合 Prisma 的命名约定,这两个字段都应小写为post
、profile
和user
。- 即使在小写之后,
User
上的post
字段仍然略有命名不当。那是因为它实际上指的是一个帖子列表 – 因此更好的名称应该是复数形式:posts
。
这些更改与生成的 Prisma Client API 相关,其中使用小写的关系字段 author
、posts
、profile
和 user
对于 JavaScript/TypeScript 开发人员来说会感觉更自然和符合习惯。因此,你可以配置你的 Prisma Client API。
因为关系字段是虚拟的(即它们不会直接在数据库中体现),所以你可以在你的 Prisma 模式中手动重命名它们,而无需触及数据库
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
posts Post[]
profile Profile?
}
在本例中,数据库模式确实遵循了 Prisma ORM 模型的命名约定(只有从内省生成的虚拟关系字段不符合约定,需要调整)。这优化了生成的 Prisma Client API 的人体工程学。
使用自定义模型和字段名称
不过,有时你可能希望对 Prisma Client API 中公开的列和表的名称进行其他更改。一个常见的例子是将数据库模式中常用的 snake_case 表示法转换为对于 JavaScript/TypeScript 开发人员来说感觉更自然的 PascalCase 和 camelCase 表示法。
假设你从基于 snake_case 表示法的内省中获得了以下模型
model my_user {
user_id Int @id @default(autoincrement())
first_name String?
last_name String @unique
}
如果你为此模型生成 Prisma Client API,它将在其 API 中拾取 snake_case 表示法
const user = await prisma.my_user.create({
data: {
first_name: 'Alice',
last_name: 'Smith',
},
})
如果你不想在你的 Prisma Client API 中使用数据库中的表和列名,你可以使用@map
和 @@map
来配置它们
model MyUser {
userId Int @id @default(autoincrement()) @map("user_id")
firstName String? @map("first_name")
lastName String @unique @map("last_name")
@@map("my_user")
}
使用这种方法,你可以随意命名你的模型及其字段,并使用 @map
(用于字段名称)和 @@map
(用于模型名称)指向底层表和列。你的 Prisma Client API 现在看起来如下
const user = await prisma.myUser.create({
data: {
firstName: 'Alice',
lastName: 'Smith',
},
})
在此页面了解更多信息:配置你的 Prisma Client API 页面。