Skip to content

How Migrations Work

Migrations in MountSQLI are pure-then-applied. Diffing and SQL generation are pure functions over your TableDef[]; only the Migrator touches the database.

flowchart LR
  A[TableDef from code] --> B[diffSchemas]
  C[Live TableDef via introspect] --> B
  B --> D[DiffResult: add/drop/alter]
  D --> E[generateMigrationSQL]
  E --> F[SQL migration file]
  F --> G[Migrator.apply]
  G --> H[_mount_migrations]
Function Input Output
diffSchemas(before, after) two TableDef[] DiffResult (changes)
generateMigrationSQL(diff, dialect) a DiffResult GeneratedMigration (SQL)
introspect(driver) a live Driver TableDef[] of the real DB

Applied steps are recorded in _mount_migrations on the database. This is the source of truth for what has run.

  • migrate status diffs the on-disk migration files against _mount_migrations to show pending work.
  • migrate apply runs pending steps in a transaction and records each.
  • You can preview SQL before it runs (generate writes files, apply runs them).
  • No generator daemon — diffing is a compiler phase, not a pre-run requirement.
  • The same diff powers the Studio’s drift report.
  • Commit migration files to version control.
  • Review generated SQL before applying to production.
  • Use a file URL (not :memory:) so _mount_migrations persists.
  • Editing a table in code but skipping migrate generate — the live DB drifts.
  • Deleting a migration file that was already applied — status reports it missing.