python manage.py makemigrations # generate a migration file from model changes
python manage.py migrate # apply pending migrations to the database
python manage.py sqlmigrate orders 0003 # preview the actual SQL a migration will run
python manage.py showmigrations # see which migrations are applied vs. pending
A migration is a versioned, reviewable Python file describing exactly how the schema changed — the same discipline Git gives your code, applied to your database structure, and critically, applied in the same order on every environment (dev, staging, production).
Two developers each add a migration on separate branches, both numbered against the same prior migration (e.g., both 0005_x depending on 0004). Django detects this as two migrations with the same dependency, forming a diverging history:
python manage.py makemigrations --merge # generates a merge migration, like a git merge commit
This is a genuinely common source of confusion on teams — it isn't a bug, it's Django correctly detecting that the migration graph branched, exactly like a Git history that needs a merge commit.
Most migrations only change schema (add a column, add an index). A data migration additionally transforms existing rows, using RunPython:
from django.db import migrations
def populate_full_name(apps, schema_editor):
# NOTE: use the historical model from apps.get_model, not the "live"
# imported model — the live model may have fields this migration doesn't know about yet
Order = apps.get_model("orders", "Order")
for order in Order.objects.all():
order.full_name = f"{order.first_name} {order.last_name}"
order.save()
class Migration(migrations.Migration):
dependencies = [("orders", "0004_order_full_name")]
operations = [migrations.RunPython(populate_full_name)]
Using apps.get_model instead of importing the real model class matters: migrations must remain correct even years later, replayed against a database that's mid-way through its history — importing the current Order class directly could reference a field that doesn't exist yet at that point in the migration sequence.