راهنمای رفع تداخل‌های Migration در Prisma

دستور prisma migrate reset را روی دیتابیس Production اجرا نکنید.

اگر پیامی مبنی بر تغییر در یک Migration یا نیاز به بازنشانی (Reset) اسکیما مشاهده کردید، متوقف شوید. بازنشانی باعث حذف تمام داده‌های شما خواهد شد. شما می‌توانید این تداخل‌ها را بدون از دست دادن هیچ داده‌ای، به صورت دستی رفع کنید.

خطاهای رایج Prisma و نحوه رفع آن‌ها

خطا: شکست Migration در حین اجرا (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]

خطا: تغییر در Migration پس از اعمال آن (عدم تطابق Checksum) • هش SHA-256 فایل Migration فعلی خود را محاسبه کنید. • مقدار checksum را در جدول _prisma_migrations به‌روزرسانی کنید. • مهم: تمام ردیف‌های مربوط به آن نام Migration را به‌روزرسانی کنید. از فیلتر کردن بر اساس rolled_back_at خودداری کنید.

خطا: نبود ستون در Shadow database (P3006) • این اتفاق زمانی رخ می‌دهد که یک Migration به ستونی ارجاع می‌دهد که در Migration بعدی ایجاد شده است. • Prisma عملیات Migration را به ترتیب برچسب زمانی (Timestamp) مجدداً اجرا می‌کند. • راه حل: کد SQL را به Migration ای منتقل کنید که ستون برای اولین بار در آنجا ایجاد شده است.

خطا: مسدود شدن دستور DROP COLUMN توسط سیاست RLS • قابلیت Row Level Security در PostgreSQL، سیاست‌ها را به ستون‌ها متصل می‌کند. • راه حل: هنگام حذف ستون‌ها از CASCADE استفاده کنید. • مثال: ALTER TABLE "my_table" DROP COLUMN IF EXISTS "tenant_id" CASCADE;

بهترین روش‌ها برای مهاجرت‌های ایمن

  • ابتدا دیتابیس را کوئری بگیرید. حدس نزنید که آیا ستون یا ایندکسی وجود دارد یا خیر. قبل از نوشتن کد Migration، از کوئری‌های مستقیم SQL برای بررسی اسکیما واقعی دیتابیس خود استفاده کنید.
  • از IF EXISTS و IF NOT EXISTS استفاده کنید. این کار باعث می‌شود Migrationهای شما Idempotent باشند. یک Migration Idempotent می‌تواند چندین بار بدون ایجاد خطا اجرا شود.
  • برای محدودیت‌ها (Constraints) از بلوک‌های DO استفاده کنید. افزودن Foreign Key را در یک شرط قرار دهید تا بررسی شود آیا نام آن Constraint از قبل وجود دارد یا خیر.
  • اگر از Row Level Security استفاده می‌کنید، همیشه برای دستورات حذف (Drop) از CASCADE استفاده کنید.

جدول خلاصه

• P3018 (شکست در حین اجرا): SQL را اصلاح کنید، سپس از resolve --rolled-back و resolve --applied استفاده کنید. • عدم تطابق Checksum: هش جدید را محاسبه کرده و تمام ردیف‌ها را در _prisma_migrations به‌روزرسانی کنید. • خطای Shadow DB: ترتیب برچسب زمانی (Timestamp) را بررسی کرده و منطق SQL را جابه‌جا کنید. • خطای RLS: عبارت CASCADE را به دستورات DROP خود اضافه کنید.

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