Interface-driven migrations for Go.
I Migrate is an interface-driven approach to managing database migrations. It was created out of a need for a migration tool that can be used in a Go project that doesn't conform to database/sql, and can execute migrations embedded in a single binary.
This project aims to fulfill the following needs:
- Migrations written in pure SQL, stored in flat files.
- CLI runner for up, down, redo, rollback, status, dry-run, etc.
- CLI template generator for timestamp-prefixed migrations.
fs.FSsupport, allowing migration files to be embedded via//go:embed.- Database driver agnostic via a sql Exec interface.
- No config files. (But config in code)
- All public API methods return errors (no panics).
- Dry-run mode to preview SQL without executing it.
For projects using database/sql, use the provided SQLDB adapter:
db, err:=sql.Open("sqlite3", "db.sqlite3")
iferr!=nil {
log.Fatal(err)
}
deferdb.Close()
executor:=imigrate.NewSQLDB(db)
migrator:=imigrate.NewIMigrator(executor, os.DirFS("."))
imigrate.CLI(migrator)//go:embed migrationsvarmigrationsFS embed.FSfuncmain() {
db, _:=sql.Open("sqlite3", "app.db")
executor:=imigrate.NewSQLDB(db)
migrator:=imigrate.NewIMigrator(executor, migrationsFS)
// WriteDirname tells Create where to write new files on disk,// since the embed.FS is read-only.migrator.WriteDirname="internal/db/migrations"imigrate.CLI(migrator)
}If your database driver does not conform to database/sql, implement the Executor interface:
typeExecutorinterface {
Exec(querystring, args...interface{}) (sql.Result, error)
GetVersions(querystring, args...interface{}) ([]int64, error)
}All public API methods return errors:
// Run all pending migrationserr:=migrator.Up(-1, 0)
// Run a specific number of migrationserr=migrator.Up(2, 0)
// Run a specific versionerr=migrator.Up(-1, 1610069160)
// Roll backerr=migrator.Down(-1, 0)
// Preview what Up would doerr=migrator.DryRun(-1, 0)Use CLIWithArgs when you need to control the argument parsing:
args:= []string{"up", "-steps=1"}
err:=imigrate.CLIWithArgs(migrator, args)CLI(migrator) is a convenience wrapper that passes os.Args[1:].
migrator:=imigrate.NewIMigrator(executor, fsys)
// Set a separate directory for writing new migration filesmigrator.WriteDirname="internal/db/migrations"// Silence migration outputmigrator.Logger=imigrate.DiscardLogger// Or provide your own loggermigrator.Logger=log.New(os.Stderr, "[migrate] ", log.LstdFlags)Example CLI usage for a tool named "migrate":
migrate create create_users_table
migrate up
migrate up -steps=1
migrate up -version=1610069160
migrate down
migrate down -steps=1
migrate redo
migrate redo -steps=2
migrate rollback
migrate rollback -steps=3
migrate status
migrate dry-run
migrate dry-run -steps=2
migrate dry-run -version=1610069160All commands accept a -silent flag to suppress output.