开发环境迁移工作流:migrate dev 详解
完整流程
npx prisma migrate dev --name added-post-tags
一条命令背后做了这些事:
- 读取
schema.prisma - 对比 当前 Schema 与上一次迁移快照的差异(快照存在
prisma/migrations/migration_lock.toml里) - 生成 新的 SQL 迁移文件到
prisma/migrations/YYYYMMDD描述/migration.sql - 应用 这条迁移到开发数据库
- 更新 快照和
_prisma_migrations表 - 触发
prisma generate重新生成 Prisma Client
步骤 2 的差异对比
Prisma 会把 Schema 的变化翻译成对应的 SQL DDL:
| Schema 变化 | 生成的 SQL |
|---|---|
| 新增 model | CREATE TABLE |
| 新增字段 | ALTER TABLE ADD COLUMN |
| 删字段 | ALTER TABLE DROP COLUMN |
| 改字段类型 | ALTER TABLE ALTER COLUMN |
| 新增 enum | CREATE TYPE(PostgreSQL) |
| 加唯一约束 | CREATE UNIQUE INDEX |
| 加外键关系 | 加列 + 加约束 |
步骤 3 的迁移文件
目录名自动用"日期 + 描述"格式:20240115_added-post-tags。里面只有一个 migration.sql 文件。
步骤 4 的破坏性变更
以下操作会被 Prisma 检测为可能丢数据,要求你确认:
- 删列(列里的数据会丢)
- 改字段类型(比如
Int→String,可能无法转换) - 删表(整表数据丢)
- 改
@default值(比如从autoincrement()改成没有默认值)
Prisma 提示后你可以继续,但更推荐手动编辑生成的 SQL 来做更安全的数据迁移(比如先加新列、用 UPDATE 回填数据、再删旧列)。
自定义迁移 SQL
有时候 Prisma 自动生成的 SQL 不够灵活,或者你需要分几步做数据迁移。可以:
- 先跑
migrate dev让它生成一个迁移文件 - 打开 那个
migration.sql,手动追加/修改 SQL - 手动执行 这个迁移(或重跑
migrate dev——Prisma 会检测到 SQL 文件已存在,让你决定怎么处理)
案例:安全重命名字段
Prisma 没有"重命名列"这个原语——它会把重命名当成"删旧列 + 加新列",导致数据丢失。正确做法:
-- migration.sql
-- 第一步:加新列
ALTER TABLE "User" ADD COLUMN "fullName" VARCHAR(255);
-- 第二步:回填数据
UPDATE "User" SET "fullName" = "name";
-- 第三步:删除旧列
ALTER TABLE "User" DROP COLUMN "name";
--create-only 参数
只想生成迁移文件但不执行(比如让你手动审阅 SQL):
npx prisma migrate dev --name temp-test --create-only
--skip-generate 参数
有时候你只想跑迁移、不想重新 generate Prisma Client:
npx prisma migrate dev --name x --skip-generate
迁移状态查询
npx prisma migrate status
输出会告诉你:
- 当前数据库里的迁移历史
- 哪些迁移已应用、哪些未应用
- Schema 和最后一次迁移快照是否一致
迁移状态不正常时(比如你手动改了数据库),status 会提示问题所在。