--- name: saleor-django-migration description: Generate Django schema migrations for the Saleor codebase using manage.py makemigrations. Use when (1) a new Django model is created, (2) model fields are added/altered/removed, (3) user explicitly asks to create a migration. This skill covers ONLY synchronous schema migrations (CreateModel, AddField, AlterField, RemoveField, etc.) — NOT data migrations with RunPython or RunSQL. If unsure whether the migration is schema-only, ask the user. --- # Saleor Django Schema Migration ## Scope This skill handles **schema-only** migrations: CreateModel, AddField, AlterField, RemoveField, AddIndex, AddConstraint, etc. It does NOT cover: - Data migrations (RunPython, RunSQL with data changes) - Async/background migrations (celery tasks, post_migrate signals) If the change requires data transformation, stop and ask the user. ## Critical Rules 1. **NEVER write migration files by hand.** Always let Django generate them. 2. **ALWAYS use `./manage.py makemigrations`** to generate migrations. 3. **Activate the virtual environment first** — run `. .venv/bin/activate` before any manage.py command. 4. **If database connection fails**, stop and ask the user to start the database. ## Workflow ### Step 1: Make model changes Edit the Django model file(s) as needed. Do not touch any migration files. ### Step 2: Generate migration ```bash . .venv/bin/activate && python manage.py makemigrations ``` If Django asks interactive questions (e.g. "Did you rename field X to Y?"), answer based on the model changes you made. ### Step 3: Read and analyze the generated migration Read every generated migration file. Verify: - It contains only schema operations (CreateModel, AddField, AlterField, RemoveField, AddIndex, etc.) - Dependencies look correct - No unexpected operations ### Step 4: Apply separation rules Apply these rules to the generated migration(s): **Rule A — One model per migration for new models:** If the migration creates MORE THAN ONE new model (multiple `CreateModel` operations), split them. Generate each separately: ```bash python manage.py makemigrations ``` If Django generates them together, delete the combined migration, then create models one at a time (add one model to models.py, run makemigrations, repeat). **Rule B — One field change per migration:** If the migration alters MORE THAN ONE field within a single model (e.g. two `AddField` or two `AlterField` operations on the same model), split into separate migrations — one per field. Delete the combined migration, make one field change at a time, and run makemigrations after each. **Exceptions (do NOT split):** - A `CreateModel` with all its fields is one operation — do not split the fields of a new model - Cross-model dependencies where Django requires them together (e.g. ForeignKey + related model creation) - Field + its index/constraint in the same migration is acceptable when auto-generated together ### Step 5: Verify Run the check command to confirm no pending migrations remain: ```bash python manage.py makemigrations --check --dry-run ``` Expected output: `No changes detected` — meaning all model changes are captured in migrations. ## Error Handling | Error | Action | |-------|--------| | `django.db.utils.OperationalError: could not connect` | Ask user to start the database | | `Conflicting migrations detected` | Stop and let user decide | | `ModuleNotFoundError` | Virtual environment not activated — run `. .venv/bin/activate` | ## Tips - Rely on autogenerated migrations for correct timestamps, sequential numbers, dependencies, and field definitions. If you must hand-edit (e.g. to split), regenerate rather than edit — delete the migration, adjust models.py, and re-run makemigrations. - When splitting, let Django figure out dependencies between the new smaller migrations. - Check the newest existing migration in the app (`ls saleor//migrations/ | tail -5`) before generating, so you can confirm the new migration number is sequential.