PATTERN Cited by 1 source
Migration script travels with application code¶
Pattern¶
The schema migration script for a feature lives in the same git repository, the same git branch, and the same pull request as the application code that depends on it. There is no separate ticket, no separate review, no separate deploy queue, no separate repo for schema changes. "Schema and data migration travels with code."
The migration tool format is platform-orthogonal — Flyway, Liquibase, Alembic, Knex, Prisma all produce migration files that fit the pattern. What's load-bearing is the same-repo + same-PR + same-review principle, not the specific tool.
Canonical statement¶
"Jen writes the migration script. Whatever her team uses – Flyway, Liquibase, Alembic, Knex, Prisma – the script lives in the code repo, alongside the application changes. Schema and data migration travels with code."
"Jen commits both the application code and the migration script. She opens a PR."
What the pattern dissolves¶
Pre-pattern, schema changes lived in separate workflows:
| Application change | Schema change (pre-pattern) |
|---|---|
| Lives in app git repo | Sometimes a separate "schema repo" |
| Reviewed by app team | Reviewed by DBA via ticket queue |
| Tested in CI | Often only tested at deploy time |
| Deployed via app pipeline | Deployed via DBA-operated migration window |
| Released atomically with code | Released before code (additive-only) or after code (rollback considerations) |
| Visible in PR diff | Sometimes invisible to PR reviewer |
The decoupling produced specific failure modes:
- PR reviewers couldn't reason about the change holistically — schema half lives elsewhere, code half lives in the PR; the review is split.
- Atomic rollback impossible — rolling back the application code didn't roll back the schema, and vice versa.
- Out-of-order deploys — schema landed before code (additive) or after code (release-coordination tax).
- Schema review queue became a bottleneck — see concepts/database-development-compensating-layer.
Post-pattern:
| Application change | Schema change (post-pattern) |
|---|---|
| Lives in app git repo | Same git repo, same directory tree |
| Reviewed by app team + (optionally) DBA | Reviewed in the same PR |
| Tested in CI | Tested in CI against an ephemeral branch |
| Deployed via app pipeline | Deployed via the same pipeline |
| Released atomically with code | Released atomically with code by construction |
| Visible in PR diff | Visible alongside the code that uses the new columns |
Why this matters under evolutionary database design¶
Evolutionary database design (Fowler 2003, Sadalage 2006) explicitly requires Practice #7 — version-control everything, including the schema. The methodology says schema changes are first-class code artefacts. But the pre-pattern industry split the workflow because of two missing capabilities:
- No per-pipeline isolation ( Practice #4 aspirational) — without isolated test environments, pre-merge migration validation was impossible, so DBAs validated by hand at deploy time.
- No CI-side validation — without copy-on-write branches, CI couldn't run migrations against production-shaped data, so the breakage class went to the DBA.
Both gaps closed in 2026 with copy-on-write branching. The pattern becomes operational because:
- The CI-ephemeral-branch pattern runs the migration on a real branch and posts the schema-diff inline.
- The paired-branch pattern gives the developer a real branch to test the migration + code together before opening the PR.
Relationship to Continuous Delivery (Humble & Farley 2010)¶
The pattern's intellectual lineage:
- Fowler 2003 — Evolutionary Database Design essay articulates Practice #7 (version-control everything, schema included).
- Sadalage 2006 — Refactoring Databases operationalises the practice with a refactoring catalog + transition mechanics.
- Humble & Farley 2010 — Continuous Delivery Chapter 12 ("Managing Data") brings migration scripts into the deployment pipeline as first-class artefacts. This is when schema-as- code reached the CI/CD movement.
- 2026 — copy-on-write branching closes the per-pipeline- isolation gap that Continuous Delivery couldn't solve in 2010.
The Databricks 2026-05-29 post canonicalises the gap explicitly:
"That methodology reached CI/CD in 2010 with Continuous Delivery (Chapter 12: Managing Data). Migrations became first-class artifacts in the deployment pipeline. The discipline of database-changes-as-code reached the broader CI/CD movement. What CD didn't solve was per-pipeline isolation: pipelines could run migrations, but they still needed a target database, and that target was shared."
(Source: same)
Migration tool list (platform-agnostic)¶
The pattern is tool-orthogonal — any of the following works:
| Tool | Language | Migration format |
|---|---|---|
| Flyway | Java (multi-DB) | SQL files, sequentially numbered, optional undo files |
| Liquibase | Java (multi-DB) | XML / YAML / JSON / SQL changesets |
| Alembic | Python (SQLAlchemy) | Python scripts with upgrade() / downgrade() |
| Knex | Node.js | JS files with exports.up / exports.down |
| Prisma | Node.js / TypeScript | Generated SQL files from schema diff |
The post explicitly lists all five as equivalent for the pattern's purposes. The substrate (Lakebase / Neon / PlanetScale) doesn't dictate the migration-tool choice — the migration tool operates against the branch's connection string, blind to the storage layer underneath.
Trade-offs¶
Upsides¶
- Holistic PR review — reviewer sees code + schema together; catches mismatches at review time.
- Atomic deploy + atomic rollback — schema change ships with the code; rollback rolls both back together.
- Single review queue — no separate DBA ticket queue blocking schema changes.
- Migration is tested with the app — not validated separately and hoped to compose at deploy time.
- Refactoring catalog becomes routine — the cost of moving a schema change into the same PR drops to zero.
Downsides¶
- Backward-compatibility considerations during multi-step rollouts — code that requires the new schema can't ship before the migration applies. Solved by expand / contract migrations (additive change in one PR, code that depends on it in a later PR after the additive change is live).
- Long-running migrations don't fit one PR cycle — a multi-hour data migration can't gate a PR. Solved by expand-only-at-PR-time + background-data-migration-after- merge shape.
- DBA review still needed for design questions — the pattern doesn't replace the DBA; it just removes the gating cost. See concepts/dba-as-design-collaborator.
- Cross-team schema changes that affect multiple application repos still need coordination at a higher altitude.
Relationship to adjacent patterns¶
- patterns/sequential-numbered-migration-files — the
file-format convention (
V001__add_inventory.sql/001_add_inventory.py) that migration tools use. The same-PR pattern composes naturally with it. - patterns/per-developer-database-branch-paired-with-code-branch — paired-branch pattern at developer altitude. The migration script lives in the developer's git branch + the database branch; both travel together.
- patterns/ci-ephemeral-database-branch-with-schema-diff-comment — paired-branch pattern at CI altitude. CI applies the migration from the same PR; the schema-diff comment shows the migration's effect.
- patterns/branch-based-schema-change-workflow — PlanetScale's product surface. Branches are separate from the application repo on PlanetScale (database branch ≠ git branch); the deploy-request is the unit of merge. The Lakebase-side flow is more deeply git-integrated — the same PR holds both halves of the change.
Seen in¶
- sources/2026-05-29-databricks-enabling-evolutionary-database-development-database-branching-with-lakebase — First canonical wiki instance of the same-PR migration pattern. Databricks 2026-05-29 Tier-3 post. Lists the five-tool platform-agnostic migration tools (Flyway, Liquibase, Alembic, Knex, Prisma), names the "schema and data migration travels with code" principle, and describes Jen's PR opening with both halves of the change in one commit. Frames the lineage from Fowler 2003 → Sadalage 2006 → Humble & Farley 2010 (Continuous Delivery, Chapter 12) → 2026 substrate change.
Related¶
- concepts/evolutionary-database-design — Practice #7 (version-control everything) requires this pattern.
- concepts/practice-4-everybody-gets-their-own-database-instance — sibling practice that the same substrate enables.
- concepts/versioned-schema-migration · concepts/schema-evolution · concepts/up-down-migration-pair — concept-layer primitives.
- concepts/database-branching — the substrate that makes the pattern workable in the team-scale shape.
- patterns/sequential-numbered-migration-files · patterns/per-developer-database-branch-paired-with-code-branch · patterns/ci-ephemeral-database-branch-with-schema-diff-comment · patterns/branch-based-schema-change-workflow — sibling patterns.
- systems/lakebase — canonical 2026 substrate.