Database Migrations
Purpose
Evolve the schema safely: every change a versioned, reviewed, immutable migration; applied in order everywhere; shaped so deploys don't break running code. Moving/transforming data is data-migration; this skill owns schema change mechanics.
When to Use
- Whenever the schema changes, and when establishing the migration workflow.
- Not for backfills/transformations (
data-migration) or seed content (seed-data).
Inputs
- Schema change intent (
relational-schema-design / document-schema-design output).
- Tooling from the data layer (
prisma-relational / drizzle-relational / mongoose-mongodb index builds), deploy flow (../../backend/backend-deployment).
Discovery Questions
- What applies migrations in each environment (deploy step — automated, ordered, once)?
- Is zero-downtime required (drives expand/contract), and what's the table size (locks!)?
- What's the actual rollback story — down migrations, or roll-forward-only with code rollback?
Responsibilities
- Establish the workflow: migrations as versioned files in the repo, generated-or-written then reviewed as code (locks, constraint validity, index build behavior), immutable once applied beyond dev — fixes are new migrations.
- Order migrations with deploys: applied before new code serves traffic (
backend-deployment); exactly-once application per environment (migration table/lock).
- Shape changes for zero-downtime where required — expand → migrate → contract:
- additive first (new nullable column/table/index), old code keeps working;
- backfill via
data-migration (batched, not in the schema migration);
- constraints tightened (NOT NULL, uniques) only after backfill;
- destructive contraction (drops/renames) only after no deployed code references the old shape.
- Respect lock behavior on big tables: concurrent index builds where the engine offers them, constraint validation split from creation, batched changes — a migration that locks a hot table for minutes is an outage.
- Define the rollback ruling: schema is usually roll-forward-only (down migrations lose data or lie) — recorded explicitly; code rolls back, schema rolls forward (
backend-deployment alignment).
- Prevent drift: CI compares schema-as-migrated vs schema-as-defined; no manual production edits — ever; MongoDB index/validator changes ride the same versioned mechanism.
Required Workflow
- Express the schema change as migration file(s); review the SQL/operations for locks and correctness.
- Classify: additive / tightening / destructive → apply expand/contract sequencing if zero-downtime.
- Coordinate backfills with
data-migration between expand and tighten.
- Verify against a production-like dataset (timing, locks) — staging first.
- Apply via the deploy pipeline; confirm drift checks pass.
Decision Rules
- Rename = add + backfill + contract, never in-place, under zero-downtime.
- NOT NULL/unique constraints arrive only after data provably satisfies them.
- Long operations (index builds, validations) use the engine's non-blocking modes or run in maintenance windows — chosen, not stumbled into.
- Down migrations exist only where they're honest; otherwise the ruling is roll-forward and everyone knows it.
Rules
- No schema change outside a migration file; no editing applied migrations.
- Every migration reviewed (locks, data safety) before merge (
../../code-review).
- Destructive migrations name the approval that authorized them (
../../../system/QUALITY_GATES.md).
Anti-Patterns
db push/auto-sync against shared environments.
- Editing an applied migration "because it was wrong."
- Schema migration + heavy backfill in one transaction, locking the table.
- Dropping a column while old code still reads it.
- Manual production hotfix SQL that no migration records (drift).
Validation Checklist
Definition of Done
A reviewed, versioned migration path for the change — safely ordered against deploys, lock-aware, expand/contract where needed, with an explicit rollback ruling and drift protection.
Related Skills
data-migration, seed-data, relational-schema-design, document-schema-design, prisma-relational, drizzle-relational, mongoose-mongodb, ../../backend/backend-deployment, backup-recovery, ../../migration-planning.
Related Knowledge
../../../knowledge/ (table sizes, downtime tolerance, environment list).
Related References
../../../references/database/migrations/ (sequencing playbooks, when populated).
Context Loading Guidance
- Requires: the schema change intent, data size, deploy flow, downtime tolerance.
- Does not require: application feature code, full schema history.
- May load:
data-migration (backfill leg), ../../backend/backend-deployment (ordering).
- Stop when: the migration files + sequencing + ruling are recorded.
Token Efficiency Guidance
Review the migration diff, not the whole schema. The expand/migrate/contract step list per change is the artifact.
1---2name: database-migrations3description: Use to plan schema-migration discipline — versioned immutable migration files, review of generated SQL, deploy-time ordering, zero-downtime expand/contract changes, rollback reality, and environment drift prevention. Data backfills are the data-migration skill.4---56# Database Migrations78## Purpose910Evolve the schema safely: every change a versioned, reviewed, immutable migration; applied in order everywhere; shaped so deploys don't break running code. Moving/transforming *data* is `data-migration`; this skill owns *schema* change mechanics.1112## When to Use1314- Whenever the schema changes, and when establishing the migration workflow.15- **Not** for backfills/transformations (`data-migration`) or seed content (`seed-data`).1617## Inputs1819- Schema change intent (`relational-schema-design` / `document-schema-design` output).20- Tooling from the data layer (`prisma-relational` / `drizzle-relational` / `mongoose-mongodb` index builds), deploy flow (`../../backend/backend-deployment`).2122## Discovery Questions2324- What applies migrations in each environment (deploy step — automated, ordered, once)?25- Is zero-downtime required (drives expand/contract), and what's the table size (locks!)?26- What's the actual rollback story — down migrations, or roll-forward-only with code rollback?2728## Responsibilities2930- Establish the workflow: migrations as **versioned files in the repo**, generated-or-written then **reviewed as code** (locks, constraint validity, index build behavior), **immutable once applied** beyond dev — fixes are new migrations.31- Order migrations with deploys: applied **before** new code serves traffic (`backend-deployment`); exactly-once application per environment (migration table/lock).32- Shape changes for **zero-downtime** where required — **expand → migrate → contract**:33 - additive first (new nullable column/table/index), old code keeps working;34 - backfill via `data-migration` (batched, not in the schema migration);35 - constraints tightened (NOT NULL, uniques) only after backfill;36 - destructive contraction (drops/renames) only after no deployed code references the old shape.37- Respect **lock behavior** on big tables: concurrent index builds where the engine offers them, constraint validation split from creation, batched changes — a migration that locks a hot table for minutes is an outage.38- Define the **rollback ruling**: schema is usually roll-forward-only (down migrations lose data or lie) — recorded explicitly; code rolls back, schema rolls forward (`backend-deployment` alignment).39- Prevent drift: CI compares schema-as-migrated vs schema-as-defined; no manual production edits — ever; MongoDB index/validator changes ride the same versioned mechanism.4041## Required Workflow42431. Express the schema change as migration file(s); review the SQL/operations for locks and correctness.442. Classify: additive / tightening / destructive → apply expand/contract sequencing if zero-downtime.453. Coordinate backfills with `data-migration` between expand and tighten.464. Verify against a production-like dataset (timing, locks) — staging first.475. Apply via the deploy pipeline; confirm drift checks pass.4849## Decision Rules5051- Rename = add + backfill + contract, never in-place, under zero-downtime.52- NOT NULL/unique constraints arrive only after data provably satisfies them.53- Long operations (index builds, validations) use the engine's non-blocking modes or run in maintenance windows — chosen, not stumbled into.54- Down migrations exist only where they're honest; otherwise the ruling is roll-forward and everyone knows it.5556## Rules5758- No schema change outside a migration file; no editing applied migrations.59- Every migration reviewed (locks, data safety) before merge (`../../code-review`).60- Destructive migrations name the approval that authorized them (`../../../system/QUALITY_GATES.md`).6162## Anti-Patterns6364- `db push`/auto-sync against shared environments.65- Editing an applied migration "because it was wrong."66- Schema migration + heavy backfill in one transaction, locking the table.67- Dropping a column while old code still reads it.68- Manual production hotfix SQL that no migration records (drift).6970## Validation Checklist7172- [ ] Change captured as versioned, reviewed migration file(s).73- [ ] Applied-before-code ordering; exactly-once mechanism.74- [ ] Expand/contract sequencing where zero-downtime required.75- [ ] Lock behavior assessed on realistic data size.76- [ ] Rollback ruling recorded (roll-forward vs honest down).77- [ ] Drift check in CI; no manual edits anywhere.7879## Definition of Done8081A reviewed, versioned migration path for the change — safely ordered against deploys, lock-aware, expand/contract where needed, with an explicit rollback ruling and drift protection.8283## Related Skills8485`data-migration`, `seed-data`, `relational-schema-design`, `document-schema-design`, `prisma-relational`, `drizzle-relational`, `mongoose-mongodb`, `../../backend/backend-deployment`, `backup-recovery`, `../../migration-planning`.8687## Related Knowledge8889`../../../knowledge/` (table sizes, downtime tolerance, environment list).9091## Related References9293`../../../references/database/migrations/` (sequencing playbooks, when populated).9495## Context Loading Guidance9697- **Requires:** the schema change intent, data size, deploy flow, downtime tolerance.98- **Does not require:** application feature code, full schema history.99- **May load:** `data-migration` (backfill leg), `../../backend/backend-deployment` (ordering).100- **Stop when:** the migration files + sequencing + ruling are recorded.101102## Token Efficiency Guidance103104Review the migration diff, not the whole schema. The expand/migrate/contract step list per change is the artifact.