در این فصل، به طور کامل نحوه مدیریت مایگریشنها (Migrations) در Django را بررسی میکنیم. این شامل فرآیند ایجاد، اعمال، و مدیریت مایگریشنها، تعامل با پایگاه دادهها، و نحوه کار با چندین پایگاه داده است. همچنین، به مباحث تغییر مدلها و اثرات آن بر پایگاه داده، مایگریشنهای دستی و سفارشی، تست سازگاری مایگریشنها، و مدیریت مایگریشنهای پیچیده در تیمهای بزرگ میپردازیم.
مایگریشنها در Django ابزاری برای اعمال تغییرات در ساختار پایگاه داده هستند. با استفاده از مایگریشنها میتوان تغییرات مدلها (مثل اضافه کردن یا حذف فیلدها، ایجاد جداول جدید، و تغییر نوع فیلدها) را به پایگاه داده اعمال کرد. هدف اصلی مایگریشنها، ایجاد هماهنگی بین ساختار کد مدلها و پایگاه داده است.
هر زمان که در مدلهای Django تغییراتی اعمال میکنید، Django به طور خودکار میتواند فایلهای مایگریشن را تولید کند که تغییرات را در پایگاه داده شما منعطف و امن اعمال میکند.
برای شناسایی تغییرات جدید در مدلها و تولید فایلهای مایگریشن جدید، از دستور makemigrations
استفاده میشود. این دستور با مقایسه مدلهای کنونی و مدلهای موجود در پایگاه داده، تغییرات جدید را شناسایی کرده و فایل مایگریشن تولید میکند.
مثال:
فرض کنید مدل User
را داریم و میخواهیم فیلدی جدید به نام age
اضافه کنیم:
class User(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField(default=0) # فیلد جدید
برای ایجاد مایگریشن جدید:
python manage.py makemigrations
پس از اجرای این دستور، یک فایل مایگریشن جدید تولید میشود که تغییرات را در پایگاه داده ثبت میکند.
بعد از ایجاد فایلهای مایگریشن، باید آنها را در پایگاه داده اعمال کنیم. برای این کار از دستور migrate
استفاده میشود.
مثال:
python manage.py migrate
این دستور تمام مایگریشنهای مورد نیاز را اعمال میکند و تغییرات را در پایگاه داده ایجاد میکند.
برای بررسی وضعیت مایگریشنها و مشاهده اینکه کدام مایگریشنها اعمال شدهاند، از دستور showmigrations
استفاده میشود.
مثال:
python manage.py showmigrations
این دستور لیستی از مایگریشنهای اعمال شده و نشده را نشان میدهد:
myapp
[X] 0001_initial
[X] 0002_add_age_field
[ ] 0003_add_email_field
علامت [X]
نشاندهنده مایگریشنهایی است که اعمال شدهاند، در حالی که [ ]
نشاندهنده مایگریشنهایی است که هنوز اعمال نشدهاند.
گاهی اوقات ممکن است بخواهید کوئری SQL که توسط Django برای هر مایگریشن تولید میشود را مشاهده کنید. برای این کار از دستور sqlmigrate
استفاده میشود.
مثال:
python manage.py sqlmigrate myapp 0002
این دستور SQL مربوط به مایگریشن 0002
را نشان میدهد.
در برخی مواقع ممکن است بخواهید به مایگریشن قبلی بازگردید. این کار با استفاده از دستور migrate
و مشخص کردن شماره مایگریشن مورد نظر انجام میشود.
مثال:
python manage.py migrate myapp 0001
این دستور پایگاه داده شما را به وضعیت مایگریشن 0001
باز میگرداند.
هنگامی که مدلهای Django تغییر میکنند، این تغییرات باید در پایگاه داده منعطف شوند. به این معنی که باید پایگاه داده به روز رسانی شود تا ساختار جدید مدلها را پذیرفته و از آن پشتیبانی کند.
اگر فیلدی جدید به مدل اضافه شود، یک دستور مایگریشن به طور خودکار تولید میشود که فیلد جدید را به جدول موجود اضافه میکند.
مثال:
افزودن فیلد email
به مدل User
:
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True) # فیلد جدید
اجرای دستور:
python manage.py makemigrations
و سپس:
python manage.py migrate
اگر فیلدی از مدل حذف شود، Django دستور مایگریشنی ایجاد میکند که آن فیلد را از جدول پایگاه داده حذف میکند.
مثال:
حذف فیلد age
از مدل User
:
class User(models.Model):
name = models.CharField(max_length=100)
# age فیلد حذف شده
اجرای دستور:
python manage.py makemigrations
و سپس:
python manage.py migrate
گاهی اوقات ممکن است بخواهید مایگریشنها را به صورت دستی یا سفارشی بنویسید. این کار زمانی مفید است که تغییرات پیچیدهای در پایگاه داده ایجاد کرده باشید که توسط Django به طور خودکار قابل شناسایی نیست.
برای ایجاد یک مایگریشن دستی، میتوانید از دستور makemigrations
استفاده کرده و فایل مایگریشنی را به صورت دستی ویرایش کنید.
مثال:
ایجاد یک مایگریشن دستی برای تغییر نوع فیلد:
# ایجاد فایل مایگریشن جدید
python manage.py makemigrations --empty myapp
سپس، فایل مایگریشن تولید شده را ویرایش کنید:
# myapp/migrations/0002_auto_20240101_1234.py
from django.db import migrations, models
def change_field(apps, schema_editor):
User = apps.get_model('myapp', 'User')
db_alias = schema_editor.connection.alias
User.objects.using(db_alias).filter(age__gt=100).update(age=100)
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RunPython(change_field),
]
قبل از اعمال مایگریشنها در محیطهای تولید، مهم است که از سازگاری و صحت آنها مطمئن شویم. برای این کار میتوانید از محیطهای تست استفاده کرده و مایگریشنها را در آنجا اعمال کنید.
قبل از اعمال مایگریشنها، از آنها در یک محیط تست (staging) استفاده کنید تا مطمئن شوید که هیچ مشکلی در پایگاه داده پیش نمیآید.
python manage.py migrate --database=test_db
در تیمهای بزرگ، هنگامی که چندین نفر به طور همزمان بر روی مدلها کار میکنند، ممکن است با مشکلات پیچیدهای در مایگریشنها روبرو شوید. برای مدیریت این مشکلات میتوانید مراحل زیر را دنبال کنید:
- هماهنگی بین تیمها: تیمها باید مطمئن شوند که هیچ گونه تضاد یا تداخل در مایگریشنها وجود ندارد.
- استفاده از مایگریشنهای کوچک: تغییرات بزرگ باید به چندین مایگریشن کوچک تقسیم شوند تا کار با آنها آسانتر شود.
- پیشگیری از مایگریشنهای نامعتبر: همیشه مایگریشنها را در محیطهای توسعه و تست اجرا کنید تا از وقوع مشکلات جلوگیری شود.
هنگامی که دو نفر همزمان بر روی مدلها کار میکنند، باید مطمئن شوند که تغییرات آنها تداخل نخواهد داشت. برای جلوگیری از این امر، میتوانید از استراتژیهای زیر استفاده کنید:
- تقسیم تغییرات به چندین مایگریشن کوچکتر
- برقراری ارتباط منظم بین اعضای تیم برای بررسی وضعیت مایگریشنها
اگر بخواهید مایگریشن ها را فقط روی یک دیتابیس خاص اعمال کنید، میتوانید از گزینه --database
استفاده کنید.
مثال:
python manage.py migrate --database=secondary
این دستور فقط مایگریشن ها را روی دیتابیس secondary
اعمال میکند.
- همیشه قبل از اعمال مایگریشنها، یک پشتیبان از پایگاه داده تهیه کنید.
- تغییرات مدلها باید با دقت انجام شود، بهویژه در محیطهای تولید.
- در محیطهای تولید (Production)، حتماً ابتدا مایگریشنها را در محیط تست یا staging اعمال کنید.