Prisma 中文文档 下载 App

重置与原型模式:db push 期间数据丢失怎么办

reset 是什么

prisma migrate reset(或 migrate dev 在检测到破坏性变更时自动触发的 reset)会:

  1. 丢弃数据库里所有 Prisma 管理的对象(表、enum、序列等)
  2. 重新应用 prisma/migrations/ 里的所有迁移
  3. 清空数据(因为表被删了重建)

什么时候会被要求 reset

场景一:原型阶段(用 db push)

原型阶段你快速改 Schema,db push 能同步大部分变化。但某些操作会导致 Prisma 提示需要重置:

⚠️ Changes to the database are destructive and require a reset:

  • Dropping the column `User.deletedAt`

All data in that column will be lost.

? Do you want to continue?

如果你确认数据不重要(原型阶段通常是的),就 reset 继续。

场景二:从 db push 切到 migrate dev

如果你之前一直用 db push 开发,现在想建立正式迁移历史,第一次跑 migrate dev 时 Prisma 会提示:

⚠️ We need to reset the database because the database schema is not managed by Prisma Migrate.

? Do you want to reset?

因为 Prisma Migrate 需要从零开始建立迁移历史——它不知道之前那些 db push 操作对应什么迁移。reset 之后,migrate dev 会把当前 Schema 当成第一次迁移写入。

场景三:你手动改了数据库

如果你绕过 Prisma 直接在数据库里跑了 DDL(比如在数据库客户端里加了一列),下次跑 migrate dev 时 Prisma 会检测到 Schema 和数据库不一致。解决方案:

reset 会丢什么

所有数据。 reset 会删表再重建,不会尝试迁移数据。这是设计使然——reset 针对的是"开发数据库"或"原型数据库"场景,生产环境绝不应该跑 reset。

保护生产数据库

确保你的 .env 文件里,生产和开发用不同的数据库 URL。migrate reset 只影响 DATABASE_URL 指向的那个数据库——只要 .env 里指向的是开发库就安全。更保险的是只在开发机上安装和运行 migrate reset 相关命令。

原型阶段不丢数据的技巧

如果你在原型阶段积累了一些不想丢的测试数据:

方法一:手动处理破坏性变更

Prisma 检测到破坏性变更会提示。你可以:

  1. 不 reset,先手动在数据库里做更安全的迁移
  2. 再 db pull 拉回最新结构
  3. 继续开发

方法二:用 seed 脚本重建数据

# 先备份现有数据(如果值得)
pg_dump mydb > backup.sql

# reset
npx prisma migrate reset

# restore(如果数据库兼容的话——reset 会改 Schema 所以可能 restore 不完整)
psql mydb < backup.sql

方法三:用 seeding 在 reset 后自动重建

在 package.json 里配置 prisma.seed:

{
  "prisma": {
    "seed": "ts-node prisma/seed.ts"
  }
}
// prisma/seed.ts
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
  // 建一些测试数据
  await prisma.user.createMany({
    data: [
      { email: 'test@example.com', name: 'Test User' },
      { email: 'admin@example.com', name: 'Admin', role: 'ADMIN' },
    ],
  })
}

main().finally(() => prisma.$disconnect())

然后 migrate reset 时加 --skip-generate(reset 已经会 generate):

npx prisma migrate reset
# reset 完成后自动执行 seed 脚本

这样每次 reset 后测试数据自动恢复,不需要手动重建。

总结

阶段推荐做法
原型阶段db push 快速迭代,接受 reset 丢数据
准备转正式跑一次 migrate dev 触发 reset → 建立基线迁移
长期维护migrate dev + 自定义 SQL 手动处理破坏性变更 + seed 脚本恢复数据
生产环境只用 migrate deploy,绝不用 reset