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.
The model
Section titled “The model”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]
Three pure functions
Section titled “Three pure functions”| 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 |
The migrations table
Section titled “The migrations table”Applied steps are recorded in _mount_migrations on the database. This is the
source of truth for what has run.
migrate statusdiffs the on-disk migration files against_mount_migrationsto show pending work.migrate applyruns pending steps in a transaction and records each.
Why pure-first
Section titled “Why pure-first”- You can preview SQL before it runs (
generatewrites files,applyruns them). - No generator daemon — diffing is a compiler phase, not a pre-run requirement.
- The same diff powers the Studio’s drift report.
Best practices
Section titled “Best practices”- Commit migration files to version control.
- Review generated SQL before applying to production.
- Use a file URL (not
:memory:) so_mount_migrationspersists.
Common mistakes
Section titled “Common mistakes”- 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.
