生产迁移:deploy / status / resolve
本教程共 54 篇 · 第 31 篇 · 更新于 2026-08-11 · 约 6 分钟阅读
本节目标:学会在生产环境用
migrate deploy安全应用迁移,用migrate status检查状态,用migrate resolve修复失败迁移。
migrate deploy:只应用,不生成
生产环境只有一条命令:
npx prisma migrate deploy
它的行为刻意保持简单:
- 对比迁移表与迁移历史,找出未应用的迁移
- 按顺序应用它们,更新
_prisma_migrations表 - 数据库不存在时自动创建
它不会:检查漂移、重置数据库、生成 Prisma Client、使用影子数据库,也不会交互式提问——这正是它能进 CI 的原因。
和 migrate dev 对照着记:dev 是「生成 + 应用 + 检查漂移」,deploy 是「只应用」。dev 面对的是可以丢的开发库,deploy 面对的是不能错的生产库,两者的保守程度完全不同。
deploy 是幂等的:重复运行不会重复应用,已应用的迁移直接跳过。它自带一道安全网——发现已应用的迁移文件被改过,会警告:
WARNING The following migrations have been modified since they were applied:
20210313140442_favorite_colors
警告不阻断执行,但意味着开发与生产的历史已经分叉,要尽快排查。
deploy 的输入只有迁移文件,输出只有数据库状态。它不管 Schema 和迁移历史是否一致——那是开发环境的 migrate dev 该管的事。这个分工让生产流程可以完全自动化:CI 里没人看提示,命令也不会等你确认。
CI 里的顺序
生产部署的正确顺序:先迁移,后启动。
npx prisma migrate deploy
npx prisma generate
node dist/server.js
先迁移后启动,否则新代码会访问不存在的列。v7 中 migrate deploy 不生成客户端,所以 generate 要单独跑(或在构建阶段完成)。generate 只读 Schema、不碰数据库,放哪一步都行。
deploy 不检测漂移,也不警告缺失的迁移文件——它假设你已经在开发环境验证过历史。所以热修复(第 34 章)后要手动用 resolve 对齐账本,deploy 自己发现不了。多环境部署时,每个环境各跑一次 deploy,迁移文件只有一份,环境之间天然一致。
Note如果生产环境用 PgBouncer 连接池,迁移命令要走直连:v7 中
datasource.directUrl已弃用,把直连地址配进prisma.config.ts的datasource.url(配DIRECT_URL环境变量)。迁移依赖 advisory lock 等特性,走连接池会报prepared statement "s0" already exists。
Note建议把 deploy 放进 CI/CD 流水线,而不是手动在服务器上敲。多实例并发部署时,Prisma Migrate 用数据库层的 advisory lock 防止两个命令同时跑,锁超时 10 秒(不可配置),拿不到锁命令会失败,需人工重跑。
migrate status:部署前体检
npx prisma migrate status
这条命令对比迁移文件与迁移表,输出哪些已应用、哪些待应用、哪些失败。输出还会提示「本地历史与数据库迁移表不同」的具体差异:哪些迁移尚未应用、哪些在库里但本地没有——排查「为什么 deploy 没生效」时最有用。任何异常(连接失败、历史不一致、存在失败迁移)都会让退出码变成 1,方便 CI 拦截。退出码 0 表示一切正常,可以直接部署;非 0 先看输出再决定。
部署前跑一遍 status 是好习惯:如果显示有失败迁移,先处理再 deploy。
migrate resolve:修复失败的迁移
生产迁移失败时(比如加 NOT NULL 列遇到已有数据),_prisma_migrations 表会记录失败状态,后续迁移会被卡住。修复思路有两条:
回滚重来——迁移执行了一半,先手动还原已执行的部分,再标记回滚:
npx prisma migrate resolve --rolled-back 20260811120000_add_bio_index
标记后这个迁移变成「可重新应用」状态,修好问题再 migrate deploy。
手工完成并标记——迁移只是卡在某一步,手工补完剩余 SQL,然后标记已应用:
npx prisma migrate resolve --applied 20260811120000_add_bio_index
resolve 只改账本,不执行任何 SQL。它只能用于失败的迁移,对已成功的迁移调用会直接报错。两个旗标都接受完整迁移名(含时间戳前缀),缩写会匹配失败。
一个具体例子:给已有数据的表加 name 唯一约束,生产库里有重名数据,迁移在创建唯一索引时失败。此时 _prisma_migrations 表里这条迁移的状态是 failed,所有后续迁移都被阻塞。要么删掉重名数据、手工补完索引后 resolve --applied;要么还原已执行的步骤后 resolve --rolled-back 重来。
Tip修复失败迁移的通用流程:
migrate status确认状态 →migrate diff生成修复 SQL →db execute手工执行 →resolve对齐账本。详细做法见第 34 章。
生产红线
把三条红线钉在墙上:
- 生产只用
migrate deploy,绝不用migrate dev - 绝不用
migrate reset——它会删库 - 不依赖任何带交互提示的命令(CI 里没人点确认)
补充一条:别在部署脚本里给 migrate dev 起别名。有人图省事把命令写进 npm script 想通用,结果生产流水线跑的就是 dev——这是最隐蔽的事故源。部署脚本里只出现 deploy、status、resolve 三个词。
migrate dev 检测到漂移会主动重置数据库,这正是生产环境最怕的行为。让开发命令待在开发环境。
Note本部分命令仅适用于关系型数据库。MongoDB 在 v7 中不被支持,需要 MongoDB 请留在 v6.19。
参考来源
- Prisma 官方文档:migrate deploy
- Prisma 官方文档:migrate status
- Prisma 官方文档:migrate resolve
- Prisma 官方文档:Development and production workflows
- HireNodeJS:Prisma ORM for Node.js: The Complete Production Guide 2026