Native migration runner
Pro Plus. Settings → Pro Plus → Migrations. Versioned SQL
migrations applied in order, tracked in a single
quay_schema_migrations table. Zero external CLI required —
goodbye, flyway / liquibase / dbmate / goose.
File layout
Section titled “File layout”Quay reads versioned migration files from a folder you point it at:
my-project/└── migrations/ ├── 0001_initial.up.sql ├── 0001_initial.down.sql ├── 0002_add_users.up.sql └── 0002_add_users.down.sql| Convention | Notes |
|---|---|
| Filename | <version>_<name>.up.sql (and optional matching .down.sql) |
| Version | Integer or semver-ish (0001, 20260509120000, 1.0.0); sorted lexicographically |
| Name | Free-form; lowercase + underscores by convention |
| Body | Raw SQL — Quay sends each file’s body to the engine through run_query |
A missing .down.sql means “no rollback for this version” — the
runner will refuse to roll back past it (asks you to add the down
or skip with a force flag).
Apply migrations
Section titled “Apply migrations”In the migrations panel:
- Pick an active SQL session (PG / MySQL / SQLite / MSSQL / DuckDB / ClickHouse — graph + cloud-warehouse engines aren’t yet wired)
- Paste the absolute path to your
migrations/folder - Click Discover — Quay reads + sorts the files, queries
quay_schema_migrationsfor what’s already applied, shows a list with ✓ (applied) / · (pending) markers - Click Apply N pending — Quay creates the tracking table if
missing, runs each pending migration’s
.up.sqlin order, records the version + name + timestamp on success - Each migration runs in its own transaction (where the engine supports it). A failure aborts that migration’s transaction + stops the run; previously-applied migrations stay applied.
Roll back
Section titled “Roll back”Rollback last runs the most-recent applied version’s .down.sql,
removes the tracking row. The dialog asks for confirmation — rollbacks
on prod also require typed-name confirm
(Confirmation rules).
Repeat to roll back further. There’s no “rollback to version X” yet — add it via N successive rollbacks.
Generate a migration
Section titled “Generate a migration”Two paths:
- Hand-write — create the
.up.sql+.down.sqlfiles with your editor of choice - Generate from schema diff — run Schema diff,
click “Save as migration” in the diff result. Quay writes a paired
<next-version>_<auto-name>.up.sql+.down.sqlinto your migrations folder
The generated migration is a starting point — review the SQL before
committing. Quay errs toward “ALTER” rather than “DROP and recreate”
where the change is reversible, but for irreversible changes
(DROP COLUMN) the auto-rollback is -- TODO: write the inverse.
Tracking table DDL
Section titled “Tracking table DDL”Quay creates this on first apply:
CREATE TABLE quay_schema_migrations ( version VARCHAR(255) PRIMARY KEY, name VARCHAR(1024) NOT NULL, applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, checksum VARCHAR(64));The dialect-appropriate version of that DDL is in the Tracking-table DDL card on the migrations panel. Copy + run on every connection you want to track migrations on.
checksum is SHA-256 of the .up.sql body. It’s recorded but not
yet enforced — a v0.4 feature is to detect when a checked-in
migration’s body has been edited after it was applied (which would
mean different environments have different schemas under the same
version number).
Common patterns
Section titled “Common patterns”- Per-environment migration paths — same
migrations/folder applied to dev / staging / prod in turn. Thequay_schema_migrationsrow is per-database, so each env tracks independently. - Squash on release — at release boundary, dump the current
schema with Backup, make it a single
0001_baseline.up.sql, archive the old per-version files. New environments restore from the baseline; existing environments are unaffected. - Multiple folders — Quay tracks one folder per session at a time. For multi-folder projects (e.g. core + per-tenant), run the panel multiple times.
What’s deferred
Section titled “What’s deferred”- NoSQL migrations (Mongo / Redis schema versioning) — patterns exist (e.g. Mongoose migrations) but Quay’s runner is SQL-only for now. Mongo-shaped migration runner is a v0.5 candidate.
- Repeatable migrations (Flyway-style
R__) for views / procedures — not yet; for now, just include them as a normal versioned migration that DROPs + CREATEs.