Squash & Internals
Squash & Baseline
Section titled “Squash & Baseline”After accumulating many migrations, you can squash them into a single
baseline migration that captures the current schema as create_table +
create_index operations.
When to squash:
- Onboarding new team members — one file vs dozens of incremental changes
- Cleaning up history — old add/drop/rename chains become noise
- Speeding up fresh deployments — new environments apply one file instead of many
# Preview what would be squashedalab squash --dry-run
# Squash all migrations into a baselinealab squashHow Squash Works
Section titled “How Squash Works”- Generates a baseline from your current schema
- Archives old migration files to
.alab/archive/<timestamp>/ - Archives database history to
migration_history.jsonin the same directory - Writes a new
001_baseline.js - Updates the
alab_migrationstable — clears old records, inserts a baseline record - Regenerates the
alab.lockfile
Old files are preserved, not deleted:
.alab/archive/20250115_120000/├── 001_initial_schema.js├── 002_add_user_email.js├── 003_add_blog_posts.js└── migration_history.jsonExisting vs New Environments
Section titled “Existing vs New Environments”Existing databases are unaffected — the runner detects the baseline’s
squashed_through revision has already been applied and skips it.
New databases apply only the baseline, then any migrations created after the squash.
How Generation Works
Section titled “How Generation Works”When you run alab new, the generator follows a deterministic algorithm.
Diff Calculation
Section titled “Diff Calculation”The generator compares your current schema files against the state stored in the
last migration (not the database). It replays all existing migrations
in-memory to reconstruct the schema, then diffs it against your schemas/
directory.
This means you don’t need a database connection to generate migrations — schema files remain the single source of truth.
Dependency Ordering
Section titled “Dependency Ordering”Tables are created in dependency order using topological sort:
- Tables with no foreign key references first
- Then tables referencing only already-created tables
- Circular references are appended in alphabetical order
Column Sorting
Section titled “Column Sorting”Columns appear in a predictable order: id first, then alphabetical, then
created_at/updated_at last. This deterministic ordering means regenerating
from the same schema always produces identical output.
Automatic Reversals
Section titled “Automatic Reversals”The down() function is auto-generated as the reverse of up():
| Forward | Reverse |
|---|---|
create_table | drop_table |
add_column | drop_column |
rename_column(old, new) | rename_column(new, old) |
rename_table(old, new) | rename_table(new, old) |
create_index | drop_index |
add_foreign_key | drop_foreign_key |
add_check | drop_check |
alter_column | alter_column (restores previous state) |
Operations like drop_table, drop_column, and sql() cannot be auto-reversed
— the generator marks these as irreversible and leaves comments in down() for
manual handling.
Code Formatting
Section titled “Code Formatting”Generated files are formatted with npx prettier when available.