Database Migrations
Schema change is a production event. Expand/contract, avoid long locks, and never invent irreversible data loss as "fine".
Workflow
- State current schema, target schema, dialect, table size class if known.
- Classify: additive, destructive, rewrite, backfill, index-only.
- Prefer expand → migrate reads/writes → contract over in-place big bang.
- Call out locking, full table rewrites, and default-value rewrites on large tables.
- Plan online backfill (batched) separate from the schema DDL when needed.
- Define rollback / forward-fix and verification queries.
Output format
## Migration plan: <change>
**Dialect:** …
**Risk:** low | medium | high
### Steps
1. …
### SQL (or migration files)
…
### Locks / performance notes
…
### App deploy ordering
…
### Verify
…
### Rollback
…
Rules
- Never drop columns/tables before code stops reading them.
- Adding NOT NULL requires a default or multi-step backfill.
- Create indexes concurrently when the dialect and ops model support it.
- Separate long backfills from transactional DDL when possible.
- State assumptions about table size; ask if missing and risk depends on it.
- Do not run destructive SQL without an explicit user goal.
Edge cases
- Multi-service shared DB: coordinate expand/contract across deployables.
- Zero-downtime: dual-write or dual-read windows spelled out.
- Data repair: treat as a scripted job with dry-run counts, not a sneaky migration.