Prismaのマイグレーション競合を解決するためのガイド

本番環境のデータベースで prisma migrate reset を実行しないでください。

マイグレーションが変更された、あるいはスキーマのリセットが必要であるというメッセージが表示された場合は、作業を中断してください。リセットを行うと、すべてのデータが削除されます。これらの競合は、データを失うことなく手動で修正することが可能です。

よくある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コードを、その列が最初に作成されるマイグレーションに移動します。

エラー: RLSポリシーによってDROP COLUMNがブロックされる • PostgreSQLのRow Level Security(行レベルセキュリティ)は、ポリシーを列に紐付けます。 • 解決策: 列を削除する際は CASCADE を使用します。 • 例: ALTER TABLE "my_table" DROP COLUMN IF EXISTS "tenant_id" CASCADE;

安全なマイグレーションのためのベストプラクティス

  • まずデータベースにクエリを投げてください。列やインデックスが存在するかどうかを推測しないでください。マイグレーションコードを書く前に、直接SQLクエリを使用して実際のデータベーススキーマを確認してください。
  • IF EXISTS および IF NOT EXISTS を使用してください。これにより、マイグレーションがべき等(idempotent)になります。べき等なマイグレーションは、エラーを引き起こすことなく複数回実行できます。
  • 制約には DO ブロックを使用してください。外部キー(Foreign Key)の追加は、その制約名が既に存在するかどうかを確認する処理でラップします。
  • Row Level Securityを使用している場合は、削除(drop)の際に常に CASCADE を使用してください。

まとめ

• P3018 (実行中に失敗): SQLを修正し、resolve --rolled-backresolve --applied を使用します。 • チェックサムの不一致: 新しいハッシュを計算し、_prisma_migrations 内のすべての行を更新します。 • Shadow DBエラー: タイムスタンプの順序を確認し、SQLロジックを移動します。 • RLSエラー: DROP 文に CASCADE を追加します。

Source: https://dev.to/aswindanu_anwar_38c31d278/the-only-guide-you-need-for-prisma-migration-conflicts-without-losing-data-6bc