首页 / Prisma ORM 入门教程 / 常见坑与排障速查

Prisma ORM 入门教程

常见坑与排障速查

本教程共 54 篇 · 第 53 篇 · 更新于 2026-08-11 · 约 4 分钟阅读

排障常见错误N+1连接池影子数据库错误码PgBouncer

本节目标:避开 8 个高频陷阱,掌握 8 项排障动作,会用错误码速查表定位问题。

社区高频问题有一半来自固定套路:连接管理、异步、查询形状、版本同步。这些坑踩一次就够,本章集中列出来当体检清单用。

八大陷阱

  1. 每个请求都 new PrismaClient()。每个实例都开自己的连接池,请求一多就打满连接(「too many clients already」)。正确做法是进程级单例:模块顶层创建一次,开发环境挂 globalThis 防热重载泄漏(见第 17 章)。

  2. 忘记 await。Prisma 查询返回 Promise,不 await 写入会静默失败、错误被吞。一律 await;再开 ESLint no-floating-promises 抓漏网的。

  3. 循环里查库(N+1)。查出列表再逐条查关联就是 N+1。用 include 一次取回:

// 错误写法:N+1,每篇文章多查一次作者
const posts = await prisma.post.findMany();
for (const post of posts) {
  await prisma.user.findUnique({ where: { id: post.authorId } });
}

// 正确写法:一条 JOIN 取回
const posts = await prisma.post.findMany({
  include: { author: { select: { id: true, name: true } } },
});
  1. include 和 select 同层混用。Prisma 直接报错:Please either use 'include' or 'select', but not both at the same time。要两者时把 select 嵌进 include:
// 错误写法:同层混用,报错
prisma.post.findMany({ include: { author: true }, select: { title: true } });

// 正确写法:select 嵌进 include
prisma.post.findMany({
  include: { author: { select: { name: true } } },
});
  1. 改完 Schema(模式)忘重新生成。schema.prisma 改了,类型不会自己更新。跑 npx prisma generate 并在 VS Code 重启 TS Server。

  2. 生产环境跑 migrate devmigrate dev 面向开发,可能重置数据库。生产只用 migrate deploy:只应用未执行的迁移。db push 也禁止上生产。

  3. 缺影子数据库migrate dev 要临时建影子数据库(shadow database)检测漂移。用户没 CREATE DATABASE 权限、托管库不让自动建库时,报 P3014。提前在 prisma.config.ts 配好 shadowDatabaseUrl 并手动建库。

  4. PgBouncer 与版本不同步。PgBouncer 事务模式下 prepared statement 冲突,报 prepared statement "s0" already exists。v7 中连接池参数已不在连接字符串上配置(?pgbouncer=true 等已失效),改为适配器构造选项;PgBouncer 需事务模式、max_prepared_statements > 0,1.21.0 及以上无需 pgbouncer=true。另一高频问题:prisma@prisma/client 版本不一致,报 schema validation (validate wasm),两个包必须锁同一版本。

八项排障清单

按「报错 → 原因 → 处理」:

  1. P1001 连不上数据库。端口、主机名、白名单或 sslmode 不对;托管库加 ?sslmode=require,Docker 先确认容器健康。
  2. P2002 唯一约束失败。往 @unique 字段插了重复值;预期可能重复的写入改用 upsert 或 connectOrCreate。
  3. P2025 记录不存在。update/delete 目标行不存在;可接受零匹配就换 updateMany/deleteMany,否则捕获后返回 404。
  4. P3014 影子库创建失败。用户没权限或托管库限制;授权 CREATE DATABASE,或手动建库并配 shadowDatabaseUrl。
  5. PgBouncer 报 prepared statement 已存在。事务模式下预编译语句冲突;v7 中连接池参数已不在连接字符串上配置(已失效),改为适配器构造选项;PgBouncer 需事务模式、max_prepared_statements > 0,1.21.0 及以上无需 pgbouncer=true
  6. 类型过期。改 schema 后没重新生成。npx prisma generate 后重启 TS Server。
  7. schema validation wasm 报错prisma@prisma/client 版本不一致,锁同一版本(如都 7.9.1)。
  8. 无服务器首次查询慢。客户端懒连接,首查才建连;启动时显式 await prisma.$connect() 提前建连。

错误码速查表

错误码含义处理
P1001连不上数据库服务器端口/白名单/sslmode
P1002连上但请求超时网络与防火墙
P1010用户被拒绝访问SSL 校验或权限配置
P2002唯一约束冲突upsert / connectOrCreate
P2003外键约束失败先建关联记录
P2024连接池取连接超时查是否每请求 new 实例
P2025目标记录不存在updateMany 或捕获
P2028事务 API 错误查超时与用法
P2034事务写冲突或死锁捕获后重试
P3009存在失败迁移,后续被阻塞migrate resolve
P3014无法创建影子数据库授权或手动建库
P3018迁移应用失败修复后 resolve

完整错误码体系见第 42 章。

Tip

开发环境开 log: ["query", "error", "warn"] 看每条 SQL,排查 N+1 最快;生产关掉。

参考来源

  • tech-insider:Prisma ORM Tutorial 2026(en-tutorials/084,八大陷阱与八项排障清单)
  • generalistprogrammer:Prisma Tutorial Complete Guide(en-tutorials/073)
  • Prisma 官方:Error Reference(orm/reference/error-reference.mdx)