Schema 结构:数据源、生成器与 PSL 语法
本教程共 54 篇 · 第 7 篇 · 更新于 2026-08-11 · 约 7 分钟阅读
本节目标:看懂 schema.prisma 的三大组成块,掌握 PSL 语法与格式化工具,学会用多文件组织 Schema。
Schema 是 Prisma 的配置文件,通常叫 schema.prisma。它是数据库的权威描述:建什么表、有什么列,都由它说了算。第 5 章我们照葫芦画瓢建过最小模型,这一章把 Schema 的每个部分拆开看明白。
三大组成块
一份 Schema 由三个部分组成,职责各不相同:
- 数据源(datasource):告诉 Prisma 连接哪个数据库。
- 生成器(generator):指定根据数据模型生成什么代码(默认是 Prisma Client)。
- 数据模型定义(model):描述业务数据长什么样,以及模型之间的关系。
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
CLI 每次执行命令都会读 Schema。prisma generate 读全部三块来生成客户端;prisma migrate dev 读数据源和模型来生成迁移。记住这条主线,后面章节的许多行为就顺理成章了。
provider 支持五种关系型数据库:postgresql、mysql、sqlite、sqlserver、cockroachdb。本书主线用 PostgreSQL 示范,SQLite 轻量跟练。MongoDB 的 mongodb 提供方在 v7 已不支持,相关内容留 v6.19。
Note一份 Schema 只能有一个数据源。多数据库的诉求(比如读写分离、多租户)靠 Prisma Client 层面的连接配置实现,而不是在 Schema 里堆多个 datasource。
数据源块:v7 只留 provider
数据源块声明数据库提供方,一份 Schema 只能有一个数据源。v7 之前,连接字符串直接写在 Schema 里:
// v6 老写法,v7 已弃用
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
v7 中 url、directUrl、shadowDatabaseUrl 全部移入 prisma.config.ts,Schema 里的数据源块只留 provider:
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
},
});
Note连接信息搬家的好处有二:一是密钥不再进入 Schema,避免误提交;二是同一份 Schema 可在不同环境复用,可移植性更好。
env() 是读取环境变量的函数。注意 v7 不再自动加载 .env,需要显式 import "dotenv/config"。
生成器块:prisma-client + output
生成器决定 prisma generate 产出什么。v7 的默认生成器是 prisma-client,它把客户端代码生成到项目内的自定义目录,output 必填:
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
output 是相对 schema.prisma 的路径。生成后,从自定义路径导入,而不是 @prisma/client:
import { PrismaClient } from "./generated/prisma/client";
可选字段还有 engineType(默认 client)、runtime(nodejs/bun/deno 等)、moduleFormat(默认按环境推断 esm/cjs)。老生成器 prisma-client-js 已废弃,新项目一律用 prisma-client。
生成产物是多个 TypeScript 文件,按需从不同入口导入:client.ts 是主入口,含 PrismaClient 和全部类型;enums.ts 只含枚举,体积最小;models.ts 含所有模型的类型。前端代码要引用类型时,导入 browser.ts(不含 PrismaClient 构造器)。
Tip一个 Schema 可以有多个生成器。比如再加一个 ERD 图生成器,跑一次
prisma generate就同时产出客户端和关系图。
环境变量:env() 与 .env
连接字符串这类敏感信息不该硬编码。env() 函数从环境变量取值,配合 .env 文件管理,完整配置示例如 §04 所述。
Notev7 不再自动加载
.env,必须显式import "dotenv/config"(并在项目里安装 dotenv)。.env记得写进.gitignore,避免密钥入库。
PSL 语法与三类注释
Schema 用 Prisma Schema Language(PSL)书写。语法规则不多:
- 块之间用空白分隔,不需要分号。
- 标识符和属性名大小写敏感,
User和user是两个名字。 - 模型名用 PascalCase(
User),字段名用 camelCase(createdAt)。 - 字段的完整形态是
名字 类型 修饰符? 属性*,属性可叠加多个,顺序随意。 Prisma、PrismaClient是保留名,别用作模型名。- 缩进不参与语法,但
prisma format会按固定规则排版,建议写完就格式化。
注释有三种,用途截然不同:
/// 三斜杠注释:进入 AST,会出现在生成的客户端 JSDoc 里
model User {
id Int @id @default(autoincrement())
// 双斜杠注释:只给人看,不进入 AST
email String @unique /// 行尾的三斜杠注释同样挂在 email 字段上
}
/*
* 块注释:和三斜杠一样进入 AST
*/
model Customer {
id Int @id
}
// 注释随意写;/// 注释会变成字段的文档,在 Prisma Studio 和编辑器提示里可见,适合写字段说明。
格式化与校验
prisma format 自动排版 Schema,规则固定、没有配置项,风格类似 Go 的 gofmt。它做三件事:配置块按 = 对齐、字段按列对齐、块属性(@@ 开头)排到块末尾。
npx prisma format
prisma validate 负责检查正确性:语法错误、悬空的关系引用、类型不匹配都能查出来。
npx prisma validate
Tip安装 Prisma 官方 VS Code 扩展后,PSL 有语法高亮,保存时自动格式化,错误会以红色波浪线标出。
多文件 Schema:按域拆分
项目变大后,所有模型挤在一个文件里难维护。Prisma 支持把 Schema 拆成多个文件。推荐结构如下:
prisma/
├── migrations # 迁移目录,与 schema.prisma 同级
├── models
│ ├── users.prisma
│ └── posts.prisma
└── schema.prisma # 主文件,必须包含 generator 块
拆分的规则有两条:主文件 schema.prisma 必须和 generator 块同目录;migrations 目录与 schema.prisma 同级。在 prisma.config.ts 中把 schema 指向目录:
export default defineConfig({
schema: "prisma/",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
拆分后跨文件引用自动解析,users.prisma 里的模型可以直接被 posts.prisma 引用。官方建议的实践:按业务域组织文件(用户相关的都放一起),文件名用 users.prisma 这种清晰命名,别用 myModels.prisma;保留一个一眼能认出的主文件放 generator 块(schema.prisma、base.prisma 都行)。
Note如果 schema 文件放在默认位置
prisma/schema.prisma,不配置也能工作。一旦拆分多文件,就必须用schema配置或--schema旗标显式指定目录。
拆不拆? 小项目单文件完全够用。几十个模型之后,超过 500 行、多人协作频繁冲突,就该按域拆分。拆分的收益是降低冲突率,代价是多了一个目录约定,别为拆分而拆分。
参考来源
- Prisma 官方文档:Prisma schema overview、Data sources、Generators、Schema location
- Prisma 官方文档:Upgrade to Prisma ORM v7(datasource url 弃用说明)