对,就是这个意思,而且完全可行------也是很多团队的做法:
开发:Prisma
migrate dev生成并验证 SQL生产:只手动执行 Git 里那份
migration.sql
流程(固定下来就这样)
开发环境(每次改表)
bash
# 1. 改 prisma/schema.prisma
# 2. 生成迁移 + 本地自动执行
npx dotenv-cli -e .env.dev -- npx prisma migrate dev --name add_xxx
# 3. 生成 Client + 改代码
npx prisma generate
# 4. 提交(重点:migration.sql 要进 Git)
git add prisma/schema.prisma prisma/migrations/
git commit -m "feat: add xxx"
此时会有例如:
prisma/migrations/20250625_add_xxx/migration.sql
生产环境(只跑 SQL,不跑 migrate dev / reset)
bash
# 0. 备份数据库(必做)
# 1. 打开本次发布对应的 migration.sql,在 MySQL 执行
# (命令行、Navicat、运维平台均可)
mysql ... < prisma/migrations/20250625_add_xxx/migration.sql
# 或复制文件里的 ALTER TABLE ... 执行
# 2. 告诉 Prisma「这条在生产已应用」(避免以后有人误跑 deploy 重复执行)
npx dotenv-cli -e .env.prod -- npx prisma migrate resolve --applied 20250625_add_xxx
# 3. 部署新版本应用(仍可用 Prisma Client 查库)
npx prisma generate # 一般在构建机/CI 做,不是生产改表
生产不要跑:
migrate devmigrate resetdb push
生产可以跑(可选):
migrate resolve --applied(只写迁移记录,不执行 SQL)migrate status(检查 dev/prod 是否一致)
为什么还要 migrate resolve
生产手动执行 SQL 后,MySQL 表已经变了,但 _prisma_migrations 表里还没有这条记录。
若不 resolve:
- 以后有人跑
migrate deploy会 再执行一遍 同一条 SQL → 可能报错(列已存在) migrate status会显示 drift / 未应用
resolve --applied = 只登记「这条迁移在生产已做过」,不重复执行 SQL。
一张图
开发:
改 schema → migrate dev → 生成 migration.sql + 本地执行
↓
Git 提交 migration.sql
↓
生产:
备份 → 手动执行 migration.sql → migrate resolve --applied
↓
部署应用(Prisma Client)
注意点(你项目)
- SQL 以 Git 为准 :生产只执行 已合并发布 的那份,不要现场改。
- 先 staging 再生产:同一文件在预发跑一遍。
- IM 仍 mysql2:表结构变了,IM 代码也要发版,不只 admin。
- Prisma Client 照用 :只是 改表 在生产不用 CLI 自动跑。
- 第一次 baseline :
0_init若生产表已存在,用resolve --applied 0_init,不要重复执行整份 CREATE。
一句话
你的方案对:开发用 Prisma migrate 生成并验证;生产只手动执行 migrations/*/migration.sql,再用 migrate resolve --applied 对齐记录。 这样既保留 Prisma 开发体验,又避免在生产跑不确定的 CLI 命令。