自省
使用 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 使用正确的区分大小写。如果没有使用双引号,PostgreSQL 将只读取所有内容为 _小写_ 字符。
展开以查看表的图形概述
用户
列名 | 类型 | 主键 | 外键 | 必需 | 默认值 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自动递增 |
姓名 | VARCHAR(255) | 否 | 否 | 否 | - |
电子邮件 | VARCHAR(255) | 否 | 否 | ✔️ | - |
帖子
列名 | 类型 | 主键 | 外键 | 必需 | 默认值 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自动递增 |
创建时间 | TIMESTAMP | 否 | 否 | ✔️ | now() |
标题 | VARCHAR(255) | 否 | 否 | ✔️ | - |
内容 | TEXT | 否 | 否 | 否 | - |
已发布 | BOOLEAN | 否 | 否 | ✔️ | false |
作者 ID | INTEGER | 否 | ✔️ | ✔️ | - |
个人资料
列名 | 类型 | 主键 | 外键 | 必需 | 默认值 |
---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自动递增 |
简介 | TEXT | 否 | 否 | 否 | - |
用户 ID | 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 相关,在该 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_ 表示法转换为_PascalCase_ 和_camelCase_ 表示法,这对于 JavaScript/TypeScript 开发人员来说感觉更自然。
假设您从基于 _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 页面。