重置与原型模式:db push 期间数据丢失怎么办
reset 是什么
prisma migrate reset(或 migrate dev 在检测到破坏性变更时自动触发的 reset)会:
- 丢弃数据库里所有 Prisma 管理的对象(表、enum、序列等)
- 重新应用
prisma/migrations/里的所有迁移 - 清空数据(因为表被删了重建)
什么时候会被要求 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 和数据库不一致。解决方案:
- 简单场景:
prisma db pull把数据库最新结构拉回 Schema - 复杂场景:手动 reset 重来
reset 会丢什么
所有数据。 reset 会删表再重建,不会尝试迁移数据。这是设计使然——reset 针对的是"开发数据库"或"原型数据库"场景,生产环境绝不应该跑 reset。
保护生产数据库
确保你的 .env 文件里,生产和开发用不同的数据库 URL。migrate reset 只影响 DATABASE_URL 指向的那个数据库——只要 .env 里指向的是开发库就安全。更保险的是只在开发机上安装和运行 migrate reset 相关命令。
原型阶段不丢数据的技巧
如果你在原型阶段积累了一些不想丢的测试数据:
方法一:手动处理破坏性变更
Prisma 检测到破坏性变更会提示。你可以:
- 不 reset,先手动在数据库里做更安全的迁移
- 再
db pull拉回最新结构 - 继续开发
方法二:用 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 |