Prisma 迁移冲突解决指南
切勿在生产数据库上运行 prisma migrate reset。
如果你看到提示说迁移已被修改或需要重置 schema,请立即停止。重置操作会删除所有数据。你可以通过手动方式修复这些冲突,而无需丢失任何数据。
常见的 Prisma 错误及其解决方法
错误:迁移在运行中途失败 (P3018)
• 修复 SQL 文件。
• 运行:npx prisma migrate resolve --rolled-back [migration_name]
• 运行:npx prisma db execute --file [path_to_sql_file]
• 运行:npx prisma migrate resolve --applied [migration_name]
错误:迁移在应用后被修改(校验和不匹配)
• 计算当前迁移文件的 SHA-256 哈希值。
• 更新 _prisma_migrations 表中的校验和。
• 重要提示:更新该迁移名称对应的所有行。不要通过 rolled_back_at 进行过滤。
错误:Shadow database 缺少列 (P3006) • 当某个迁移引用了由后续迁移才创建的列时,就会发生这种情况。 • Prisma 会按时间戳顺序重放迁移。 • 解决方法:将 SQL 代码移动到该列首次创建的那个迁移文件中。
错误:DROP COLUMN 被 RLS 策略拦截
• PostgreSQL 的行级安全性 (Row Level Security) 将策略与列绑定在一起。
• 解决方法:删除列时使用 CASCADE。
• 示例:ALTER TABLE "my_table" DROP COLUMN IF EXISTS "tenant_id" CASCADE;
安全迁移的最佳实践
- 首先查询数据库。 不要猜测列或索引是否存在。在编写迁移代码之前,使用直接的 SQL 查询来检查实际的数据库 schema。
- 使用
IF EXISTS和IF NOT EXISTS。 这能使你的迁移具有幂等性 (idempotent)。幂等迁移可以多次运行而不会导致错误。 - 对约束使用
DO块。 将添加外键的操作封装在检查约束名称是否已存在的逻辑中。 - 如果使用了行级安全性 (Row Level Security),在执行删除操作时请务必使用
CASCADE。
摘要表
• P3018 (运行中途失败):修复 SQL,然后使用 resolve --rolled-back 和 resolve --applied。
• 校验和不匹配:计算新哈希值并更新 _prisma_migrations 中的所有行。
• Shadow DB 错误:检查时间戳顺序并移动 SQL 逻辑。
• RLS 错误:在 DROP 语句中添加 CASCADE。
