Skip to content

meta migrate writes un-replayable statements into the committed chain, breaking apply-pending's fresh-database contract #313

Description

@dmealing

meta migrate will write a bare DROP TABLE "x" into a committed migration when x exists in the live database and is absent from the metadata — even when no migration in the chain ever creates x. In our case another tool (drizzle-kit) owned that table.

Replaying the chain against an empty database then dies:

$ meta migrate apply-pending --db postgresql://…/fresh
meta: migrate apply-pending: apply failed: table "arena_season_standing" does not exist

Nothing warns at generation time, so the chain looks healthy until someone actually tries to provision a fresh database. Ours was broken for roughly three months before anyone noticed; the only working development database left on the machine was a leftover container from a CI run.

This directly contradicts the documented contract for apply-pending, from meta migrate --help:

apply-pending Replay committed migration files against --db (no diff); provisions a fresh/CI database. postgres/sqlite only.

Two asks

  1. Emit DROP TABLE IF EXISTS / DROP VIEW IF EXISTS for objects the chain does not itself create. Postgres and SQLite both support it, and it costs nothing when the object is present. The drop is a legitimate convergence step for the database it was generated against; it just must not become a landmine for every future replay.

  2. Let meta verify assert that the committed chain replays from empty. The machinery already exists — apply-pending against a scratch database, then --from-db --dry-run and check for no schema changes. As a gate it turns a silent months-long rot into a failing build on the commit that introduces it. We ended up writing exactly this as a project-level integration test; it feels like it belongs in the tool.

Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions