Running Migrations
CLI Usage
Migrations are run through the application CLI:
Up (Apply Pending)
lemmego run migrate upApply a specific number of migrations:
lemmego run migrate up --step=3Down (Rollback)
Rollback the last batch:
lemmego run migrate downRollback multiple batches:
lemmego run migrate down --step=2Status
lemmego run migrate statusOutput:
[2025-07-06 00:00:01] create_users_table .................... 2025-07-06 12:00:00
[2025-07-06 00:00:02] create_posts_table .................... PendingCreate New Migration
lemmego run migrate create create_posts_tableOr from outside the app:
lemmego g migration create_posts_tableHow Migration Tracking Works
The migration system creates a schema_migrations table in your database:
CREATE TABLE schema_migrations (
version VARCHAR(255),
batch INT
);- version — The migration’s version string (e.g.,
20250706000001) - batch — The batch number when the migration was applied
When running up:
- Pending migrations are collected in version order
- A new batch number is created (max batch + 1)
- Each migration runs inside a transaction
- On success, the migration’s version and batch are recorded
- If any migration in the batch fails, only that migration is rolled back
When running down:
- The last batch number is identified
- Migrations in that batch are rolled back in reverse version order
- Each rollback runs inside a transaction
- The migration record is removed from
schema_migrations
Programmatic Use
import "github.com/lemmego/migration"
m := migration.GetMigrator()
// Initialize (creates tracking table)
err := m.Init()
// Apply all pending migrations
err := m.Up(-1)
// Apply 2 migrations
err := m.Up(2)
// Rollback latest batch
err := m.Down(-1)
// Rollback 1 batch
err := m.Down(1)
// Print status
m.MigrationStatus()Database Connection
The migrator reads the DB_DRIVER environment variable to determine the dialect. Database connection parameters are configured through environment variables:
| Variable | Default | Description |
|---|---|---|
DB_DRIVER | sqlite | Database driver (sqlite, mysql, pgsql) |
DB_HOST | 127.0.0.1 | Database host |
DB_PORT | (driver default) | Database port |
DB_DATABASE | storage/database.sqlite | Database name/path |
DB_USERNAME | root | Database user |
DB_PASSWORD | `` | Database password |
Best Practices
- One change per migration — Keep migrations focused on a single schema change
- Always write a down migration — Ensure every change is reversible
- Test both directions — Run
upthendownto verify correctness - Don’t modify existing migrations — Create a new migration instead
- Use version control — Migrations should be committed to git