django-migrations
Database migrations best practices, NEVER editing old migrations, and generating data migrations.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Database migrations best practices, NEVER editing old migrations, and generating data migrations.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Models, Django ORM, query optimization, and transactions
Testing, security, authentication, caching, logging, performance, and deployment
Test layout, factory_boy over fixtures, and conftest.py structure.
admin.py, forms.py, file uploads, and the Django admin performance guide
services.py, selectors.py, Celery tasks, Signals, and background processing
Project structure, clean architecture principles, and the Service Layer pattern
| name | django-migrations |
| description | Database migrations best practices, NEVER editing old migrations, and generating data migrations. |
Migrations represent the state of the database schema. They should be append-only and deterministic. Never modify old migrations.
❌ Anti-pattern: Adding migrations/ to .gitignore.
Why?
Migrations act as version control for your database. If they are ignored, each developer generates conflicting schema changes (e.g., 0002_userA.py vs 0002_userB.py), leading to massive team conflicts and breaking your ability to rollback deployments safely.
✅ Recommended: Treat migrations as production code. Always commit them to your repository to guarantee a deterministic, linear schema history across the entire team and production environments.
❌ Anti-pattern: Editing an old, already-committed migration file when you want to change a field (e.g. changing max_length in 0001_initial.py).
Why?
If you modify an existing migration file, it causes a mismatch between your database state, the state on other developers' machines, and the state in production. Django tracks which migrations have been applied using the django_migrations table. Altering a file that has already been applied will lead to severe inconsistencies and "InconsistentMigrationHistory" errors.
✅ Recommended: Always create a new migration for any schema change.
models.py.python manage.py makemigrations <app_name>.0002_new_migration.py).Always give migrations descriptive names using the --name (or -n) flag.
✅ Recommended:
python manage.py makemigrations users --name add_stripe_customer_id
This generates a file like 0003_add_stripe_customer_id.py instead of 0003_auto_20260715_1200.py.
When you need to backfill or migrate data in the database, do not write a standalone script. Write a Data Migration using RunPython.
✅ Recommended Workflow:
Create an empty migration:
python manage.py makemigrations myapp --empty --name backfill_data
Open the generated file and add a RunPython operation:
# myapp/migrations/0004_backfill_data.py
from django.db import migrations
def backfill_data_forward(apps, schema_editor):
# Always use apps.get_model in migrations!
MyModel = apps.get_model('myapp', 'MyModel')
for obj in MyModel.objects.iterator():
obj.new_field = obj.old_field.upper()
obj.save(update_fields=['new_field'])
def backfill_data_reverse(apps, schema_editor):
# Optional: define how to reverse the migration
pass
class Migration(migrations.Migration):
dependencies = [
('myapp', '0003_add_new_field'),
]
operations = [
migrations.RunPython(backfill_data_forward, backfill_data_reverse),
]
Important: Always use apps.get_model('app_name', 'ModelName') inside a RunPython function instead of importing the model directly. This ensures you are querying against the schema state as it existed at the time of the migration.