第 2 篇:用 PostgreSQL 从零搭建你的第一个 Prisma 项目

在第一篇里,我们从宏观视角认识了 Prisma。接下来这一篇,我们直接从一个真实项目起步:使用 Prisma 7 + Next.js 16.2.2 + PostgreSQL + pnpm,从空目录走到“能在页面上看到数据库里的第一条 User 记录”。
你会完成:
创建一个 Next.js 16.2.2 项目(App Router);
配置 pnpm 作为包管理器;
准备 PostgreSQL 数据库;
初始化 Prisma 7(包含 prisma.config.ts);
定义第一个
User模型并迁移到数据库;在 Next.js Server Component 中使用 Prisma Client 查询并渲染数据。
完整命令总览(速查)
先给这一篇用到的所有关键命令,一目了然:
# 1. 确认 / 安装 pnpm
corepack enable
corepack prepare pnpm@latest --activate
# 2. 创建 Next.js 16.2.2 项目
pnpm create next-app@16.2.2 prisma-next-demo
cd prisma-next-demo
# 3. 安装 Prisma 7 + PostgreSQL 相关依赖
pnpm add -D prisma tsx @types/node @types/pg
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
# 4. 初始化 Prisma 7
pnpm prisma init
# 5. 根据 schema 生成并应用第一次迁移
pnpm prisma migrate dev --name init
# 6. 检查迁移状态(可选)
pnpm prisma migrate status
# 7. 打开 Prisma Studio(可视化插入数据)
pnpm prisma studio
# 8. 启动 Next.js 开发服务
pnpm dev
后面正文会一步步解释每条命令背后在做什么。
1. 准备环境:Node.js、pnpm、PostgreSQL
1.1 Node.js 与 pnpm
确保你已经安装了 Node.js(建议 18+),然后用 Corepack 开启 pnpm:
corepack enable
corepack prepare pnpm@latest --activate
pnpm -v
看到版本号说明 pnpm 可用。
1.2 准备 PostgreSQL
你可以用任何方式提供 PostgreSQL,这里给一个最常见的 Docker 示例:
docker run -itd \
-e POSTGRES_USER=prisma \
-e POSTGRES_PASSWORD=prisma \
-e POSTGRES_DB=next_prisma_demo \
-p 5432:5432 \
--name next-prisma-postgres \
postgres
我们约定:
用户:
prisma密码:
prisma数据库:
next_prisma_demo端口:
5432
后面 .env 中的 DATABASE_URL 会写成:
DATABASE_URL="postgresql://prisma:prisma@localhost:5432/next_prisma_demo?schema=public"
如果你用的是云端 PostgreSQL(Neon / Supabase / Railway / Prisma Postgres),把连接串替换掉即可。
2. 用 pnpm 创建 Next.js 16.2.2 项目
在你准备好的目录里执行:
pnpm create next-app@16.2.2 prisma-next-demo
cd prisma-next-demo
交互向导中,建议选择:
TypeScript:Yes
ESLint:Yes
Tailwind CSS:可以 Yes(后续 UI 会舒服很多)
使用
src/目录:随意,这里下面示例假设 不使用 src,即app/在根目录下; nextjsApp Router:Yes
Import alias:保留默认
@/*。
这一步结束后,你已经有了一个 Next.js 16.2.2 App Router 项目骨架。
3. 安装 Prisma 7 与 PostgreSQL 相关依赖
根据 Prisma 7 官方 Postgres Quickstart 的推荐,我们需要:CLI + Client + PostgreSQL adapter + 驱动。
在项目里执行:
pnpm add -D prisma tsx @types/node @types/pg
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
角色说明:
prisma:CLI 工具(pnpm prisma ...);@prisma/client:根据 schema 生成的 TypeScript 客户端;@prisma/adapter-pg:Prisma 7 推荐的 PostgreSQL 驱动适配器;pg:node-postgres 驱动;dotenv:读取.env;tsx:以后写 seed 脚本会很方便。
4. 初始化 Prisma 7:生成配置与 schema
Prisma 7 推荐使用 prisma init 来生成包括 prisma.config.ts 在内的一套默认配置。
在项目根目录执行:
pnpm prisma init
执行后你会看到多了这些文件:
prisma/schema.prismaprisma.config.ts.env
这三个文件分别承担:
Schema:描述数据模型;
Config:告知 Prisma CLI schema/migrations/数据源等配置;
.env:提供
DATABASE_URL这样的环境变量。
4.1 配置 .env 中的 DATABASE_URL
打开 .env,按照前面准备的 PostgreSQL 填入连接串:
DATABASE_URL="postgresql://prisma:prisma@localhost:5432/next_prisma_demo?schema=public"
如果使用 Prisma Postgres,这里就填 Prisma 控制台里提示的 PostgreSQL 连接 URL。注意使用 postgresql:// 形式。
4.2 配置 prisma.config.ts
Prisma 官方 Next.js 指南中给出的配置方式大致如下:
// prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config'
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
},
datasource: {
url: env('DATABASE_URL'),
},
})
这段配置说明:
Prisma CLI 使用
prisma/schema.prisma作为 schema 文件;数据库迁移存放在
prisma/migrations;数据源 URL 从环境变量
DATABASE_URL读取;使用
dotenv/config自动加载.env。
5. 编写第一个 Prisma Schema:User 模型
打开 prisma/schema.prisma,改成一个最小可用的版本:
// prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}
这里有几个点:
使用
provider = "prisma-client",配合自定义output目录../generated/prisma是 Prisma 7 的推荐写法之一;datasource 明确为
postgresql;User模型包含:自增 Int 主键
id;普通字符串字段
name;带唯一约束的
email;自动填充当前时间的
createdAt。
后面所有 Prisma Client 的类型、安全性等,都源自于这个 schema。
6. 生成并应用第一次迁移(开发环境)
Prisma 官方推荐的工作流是:开发环境用 migrate dev,生产环境用 migrate deploy。
在项目根目录执行:
pnpm prisma migrate dev --name init
它会:
根据当前
schema.prisma和数据库状态生成一个迁移;把迁移 SQL 写入
prisma/migrations/*/migration.sql;应用到你的 PostgreSQL 数据库;
生成或更新 Prisma Client。
如果执行成功,你可以顺便看一下迁移状态:
pnpm prisma migrate status
它会显示哪些迁移已应用、当前数据库是否与 schema 同步。
面向生产环境的提醒(以后会详细展开):
开发环境用migrate dev很舒服,但生产环境请只用migrate deploy,并把它放进 CI/CD 流水线,而不是在运维机上手工执行。
7. 在 Next.js 中创建 Prisma Client 单例
为了在 Next.js(尤其是开发环境有热重载)中安全地使用 Prisma Client,官方 Next.js 指南推荐采用“单例 + adapter”的写法。
在项目中新建 lib/prisma.ts:
// lib/prisma.ts
import { PrismaClient } from '../generated/prisma'
import { PrismaPg } from '@prisma/adapter-pg'
const connectionString = process.env.DATABASE_URL
if (!connectionString) {
throw new Error('DATABASE_URL is not set')
}
const adapter = new PrismaPg({ connectionString })
const globalForPrisma = globalThis as unknown as {
prisma?: PrismaClient
}
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
adapter,
})
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}
这一段代码体现了几个关键理念:
使用
PrismaPgadapter 把 Prisma Client 接到 PostgreSQL;在开发环境下,把 PrismaClient 实例挂到
globalThis上,避免 Next.js 热重载时创建过多连接;在生产环境中正常创建一个实例,不污染全局。
后续整个项目只需要从 lib/prisma 导入 prisma,不用再重复创建。
8. 在 Next.js 首页做第一次数据库查询
接下来,我们在 app/page.tsx 里用 Prisma 查询 User 表,并在页面上渲染结果。
编辑 app/page.tsx:
// app/page.tsx
import { prisma } from '@/lib/prisma'
export default async function Home() {
const users = await prisma.user.findMany({
orderBy: { createdAt: 'desc' },
})
return (
<main style={{ padding: '32px' }}>
<h1>Prisma 7 + Next.js 16.2.2 + PostgreSQL</h1>
<p>当前用户数量:{users.length}</p>
<ul>
{users.map((u) => (
<li key={u.id}>
{u.name} - {u.email}
</li>
))}
</ul>
</main>
)
}
因为这是一个 Server Component(默认就是),可以直接在函数体里使用 await prisma.user.findMany,这一点是 Next.js App Router 与 Prisma 搭配时非常自然的地方。
现在唯一的问题是数据库里还没有用户数据,我们马上来补一条。
9. 用 Prisma Studio 插入第一条 User
Prisma Studio 是官方提供的 Web UI,可以在浏览器里直接查看和编辑数据。
在项目根目录执行:
pnpm prisma studio
浏览器会打开一个界面,左侧可以看到 User 表:
点击
User;点击 “Add Record”;
填写例如:
name:
Aliceemail:
alice@example.com;
保存。
回到终端,启动 Next.js 开发服务器:
pnpm dev
打开浏览器访问 http://localhost:3000,你应该会看到:
标题;
“当前用户数量:1”;
列表里有
Alice - alice@example.com。
到这里,这条完整链路已经打通:浏览器 → Next.js App Router → Prisma Client → PostgreSQL → 返回数据 → 页面渲染。
10. package.json 示例(Prisma + Next.js + pnpm 场景)
为了方便你对照,这里给一个典型的 package.json 片段(只保留和这一篇相关部分),你可以按需调整:
{
"name": "prisma-next-demo",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:deploy": "prisma migrate deploy",
"prisma:studio": "prisma studio"
},
"dependencies": {
"@prisma/adapter-pg": "^7.0.0",
"@prisma/client": "^7.0.0",
"dotenv": "^16.0.0",
"next": "16.2.2",
"pg": "^8.0.0",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/pg": "^8.0.0",
"prisma": "^7.0.0",
"tsx": "^4.0.0",
"typescript": "^5.0.0"
}
}
版本号你可以按实际安装结果调整(
^7.0.0只表明是 Prisma 7 大版本);把
prisma:migrate/prisma:deploy脚本加进去,后续 CI/CD 会更方便调用。
11. 常见报错与排查思路
11.1 Error: P1001 无法连接数据库
典型报错内容会包含 “The database server was reached but timed out” 或 “Cannot reach database server”。常见原因:
Docker 容器没启动 / PostgreSQL 没跑起来;
.env里的DATABASE_URL写错(用户名/密码/库名/端口);数据库防火墙规则限制(远程云库时)。
排查建议:
确认 Docker 容器在运行:
docker ps;用 psql / GUI 工具单独连一次数据库确认连接串正确;
确保 Next.js 项目和数据库在网络上可互通。
11.2 Error: DATABASE_URL is not set
在 lib/prisma.ts 里我们主动检查了 process.env.DATABASE_URL,如果没有就抛错。
常见原因:
.env文件没创建;.env在错误路径(不是项目根目录);启动命令不在项目根目录执行。
排查建议:
确认
.env与package.json在同一目录;确认是从项目根目录执行
pnpm dev;重启开发服务器让环境变量重新加载。
11.3 relation "User" does not exist
说明数据库里还没有对应表,但你已经调用了查询。常见原因:忘记跑 migrate dev 或 migrate deploy。
解决方案:
pnpm prisma migrate dev --name init
之后再重新启动 pnpm dev。
11.4 Next.js 开发环境连接数过多 / warn
如果你在开发时频繁看到类似 “too many clients already” 的 Postgres 报错,通常是 PrismaClient 被多次 new 导致连接池堆积。
解决方案:
确认
lib/prisma.ts使用了全局单例模式(globalThis.prisma);确认所有地方都是
import { prisma } from '@/lib/prisma',没有自己手动new PrismaClient。
12. 小结:这一篇之后,你已经有了“可扩展”的项目起点
这一篇我们有意识地把“从零跑通 Prisma”这件事放在了 Prisma 7 + Next.js 16.2.2 + pnpm + PostgreSQL 的组合里,而不是单独的脚本项目,这样后续所有实战篇(Next.js、MCP、AI 辅助开发)都能顺畅接上。
此时你已经拥有:
一个现代化的 Next.js App Router 项目骨架;
一套 PostgreSQL 数据库和可追踪的迁移历史;
一个基于 Prisma 7、适配 PostgreSQL 的 Client 单例;
第一条从页面发出的、类型安全的数据库查询。
参考链接
Prisma文档
https://www.prisma.io/docs/getting-started/prisma-orm/quickstart/postgresql
https://www.prisma.io/docs/guides/use-prisma-in-pnpm-workspaces
https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production
Github