اگر با خطای Migration در Django مواجه شده‌اید، معمولا مشکل از ناهماهنگی بین مدل‌ها، فایل‌های Migration یا دیتابیس است. این خطا یکی از رایج‌ترین مشکلات پروژه‌های جنگو محسوب می‌شود و بیشتر برنامه نویس‌ها حداقل یک بار با آن درگیر می‌شوند. خوشبختانه بیشتر این خطاها قابل حل هستند؛ فقط باید بدانید دقیقا چه چیزی باعث خراب شدن Migration شده است.

Migration در Django دقیقا چیست؟

Migration در Django سیستمی است که تغییرات مدل‌ها را به دیتابیس منتقل می‌کند. هر بار که مدل جدیدی می‌سازید یا فیلدی را تغییر می‌دهید، جنگو یک فایل Migration تولید می‌کند تا ساختار دیتابیس به روز شود.

به زبان ساده، Migration نقش مترجم بین Model و Database را دارد.

مثلا وقتی این فیلد را اضافه می‌کنید:

class Product(models.Model):
    title = models.CharField(max_length=200)

جنگو متوجه می‌شود که باید یک ستون جدید داخل دیتابیس ساخته شود.

چرا خطای Migration در Django اتفاق می‌افتد؟

این مشکل دلایل مختلفی دارد اما چند مورد از بقیه رایج‌تر هستند.

حذف یا تغییر دستی فایل‌های Migration

بعضی توسعه دهنده‌ها برای سریع‌تر شدن کار، فایل های Migration را دستی حذف می‌کنند. این کار معمولا باعث ناهماهنگی شدید بین دیتابیس و پروژه می‌شود.

مثلا فایل Migration حذف شده اما اطلاعات آن هنوز داخل جدول django_migrations ذخیره شده است.

در این حالت خطاهایی مثل این ظاهر می‌شوند:

django.db.migrations.exceptions.NodeNotFoundError

یا:

InconsistentMigrationHistory

ناهماهنگی بین دیتابیس و مدل‌ها

گاهی مدل‌ها تغییر کرده اند اما Migration جدید ساخته نشده است.

مثلا فیلدی را حذف کرده‌اید اما هنوز Migration اجرا نشده:

class UserProfile(models.Model):
    age = models.IntegerField()

بعد فیلد age را پاک می‌کنید اما دستور Migration اجرا نمی‌شود.

در نتیجه جنگو هنگام اجرای پروژه دچار خطا می شود.

اجرای Migration روی چند سیستم مختلف

این اتفاق در پروژه‌های تیمی خیلی رایج است. مثلا یکی از اعضای تیم Migration جدید ساخته اما شما آن فایل را Pull نکرده‌اید.

در نتیجه دیتابیس شما با نسخه اصلی پروژه هماهنگ نیست.

این مشکل معمولا چنین اروری تولید می‌کند:

No migrations to apply

در حالی که پروژه عملا خراب است.

تغییر نام App یا Model

وقتی اسم App یا Model تغییر می‌کند، Django بعضی وقت ها دیگر نمی تواند ارتباط Migration های قبلی را پیدا کند.

مثلا:

class Product(models.Model):

تبدیل شده به:

class ShopProduct(models.Model):

اما Migration مربوط به تغییر نام به درستی ساخته نشده است.

رایج‌ترین خطاهای Migration در Django

خطای InconsistentMigrationHistory

این خطا یعنی ترتیب Migration ها به هم ریخته است.

معمولا زمانی اتفاق می‌افتد که:

  • Migration ها دستی حذف شده باشند
  • Branch های مختلف Git با هم تداخل پیدا کرده باشند
  • بعضی Migration ها اجرا شده باشند و بعضی نه

راه حل اولیه:

python manage.py showmigrations

این دستور وضعیت همه Migration ها را نمایش می‌دهد.

خطای No such table

این خطا یعنی Django انتظار دارد جدول وجود داشته باشد اما داخل دیتابیس نیست.

نمونه خطا:

OperationalError: no such table

معمولا علت:

  • اجرا نشدن Migration
  • پاک شدن دیتابیس
  • اجرای ناقص Migration

راه حل:

python manage.py makemigrations
python manage.py migrate

خطای Duplicate Column

گاهی یک ستون قبلا داخل دیتابیس ساخته شده اما Django دوباره می‌خواهد آن را ایجاد کند.

نمونه خطا:

ProgrammingError: column already exists

این اتفاق معمولا زمانی رخ می‌دهد که:

  • Migration ناقص اجرا شده
  • تغییرات دستی روی دیتابیس انجام شده
  • Migration دوباره اجرا شده باشد

روش اصولی حل خطای Migration در Django

مرحله اول: بررسی وضعیت Migration ها

اول همیشه این دستور را اجرا کنید:

python manage.py showmigrations

Migration هایی که تیک خورده اند اجرا شده‌اند.

این مرحله کمک می کند بفهمید مشکل دقیقا از کجا شروع شده است.

مرحله دوم: ساخت Migration جدید

اگر مدل‌ها تغییر کرده اند:

python manage.py makemigrations

بعد:

python manage.py migrate

خیلی وقت‌ها مشکل همینجا حل می‌شود.

مرحله سوم: بررسی فایل‌های Migration

پوشه migrations را بررسی کنید.

نباید:

  • فایل تکراری وجود داشته باشد
  • فایل ناقص باشد
  • شماره Migration ها به هم ریخته باشند

مثلا این ساختار درست است:

0001_initial.py
0002_product_price.py
0003_remove_product_price.py

مرحله چهارم: استفاده از Fake Migration

بعضی وقت‌ها دیتابیس قبلا تغییر کرده اما Django از آن خبر ندارد.

در این شرایط می‌توانید از Fake Migration استفاده کنید:

python manage.py migrate --fake

اما این دستور خطرناک است.

اگر اشتباه استفاده شود، ساختار دیتابیس کاملا خراب می‌شود.

چه زمانی باید Migration ها را پاک کنیم؟

پاک کردن Migration آخرین راه حل است؛ نه اولین راه.

بعضی برنامه نویس‌ها سریع این کار را انجام می‌دهند:

find . -path "*/migrations/*.py" -not -name "__init__.py" -delete

این روش در پروژه واقعی ممکن است فاجعه ایجاد کند.

فقط زمانی Migration ها را پاک کنید که:

  • پروژه هنوز اول کار باشد
  • دیتابیس مهمی نداشته باشید
  • نسخه بکاپ موجود باشد

بهترین روش جلوگیری از خطای Migration در Django

همیشه بعد از تغییر Model ها Migration بسازید

این اشتباه خیلی رایج است:

  • مدل تغییر می‌کند
  • پروژه Commit می‌شود
  • Migration فراموش می‌شود

بعد بقیه اعضای تیم پروژه را اجرا می‌کنند و همه چیز خراب می‌شود.

فایل‌های Migration را داخل Git نگه دارید

بعضی افراد Migration ها را داخل .gitignore قرار می‌دهند.

این کار اشتباه بزرگی است.

Migration بخشی از ساختار پروژه است و باید Version Control شود.

روی دیتابیس Production تغییر دستی ندهید

تغییر مستقیم جدول‌ها داخل MySQL یا PostgreSQL معمولا دردسر ایجاد می‌کند.

اجازه دهید فقط Django ساختار دیتابیس را مدیریت کند.

قبل از Deploy تست Migration بگیرید

قبل از انتشار پروژه این دستور را اجرا کنید:

python manage.py migrate --plan

این دستور نشان می‌دهد دقیقا چه تغییراتی قرار است اجرا شود.

در پروژه‌های تیمی Branch ها را مدیریت کنید

خیلی از مشکلات Migration از Git Branch ها شروع می‌شوند.

اگر دو نفر همزمان Migration بسازند، احتمال Conflict بالا می‌رود.

بهتر است:

  • قبل از ساخت Migration آخرین تغییرات Pull شود
  • Migration ها سریع Merge شوند
  • شماره Migration ها بررسی شوند

آیا حذف کامل دیتابیس راه حل خوبی است؟

برای پروژه واقعی تقریبا نه.

خیلی‌ها وقتی Migration خراب می شود سریع دیتابیس را پاک می‌کنند:

rm db.sqlite3

این روش شاید در پروژه آموزشی جواب بدهد اما در پروژه واقعی می تواند باعث از دست رفتن اطلاعات شود.

همیشه اول مشکل اصلی را پیدا کنید.

جمع بندی

مشکل Migration در Django معمولا از ناهماهنگی بین Model ها، فایل های Migration و دیتابیس ایجاد می‌شود. بیشتر این خطاها به خاطر حذف دستی فایل‌ها، مدیریت اشتباه Git یا تغییرات مستقیم روی دیتابیس اتفاق می‌افتند. اگر روند Migration را اصولی مدیریت کنید، بیشتر این مشکلات اصلا به وجود نمی‌آیند.