Migrate for Go
ActiveRecord-style schema migrations for Go.
A small, dependency-free, ActiveRecord-flavoured schema-migration toolkit for Go built entirely on top of the standard library's database/sql package — no third-party packages, no cgo. A Migration carries a uint64 Version, a Name, and a pair of directions expressed either as a Go func(ctx, *sql.Tx) error or as raw SQL text; a Migrator wraps a *sql.DB, maintains a schema_migrations bookkeeping table, and drives migrations forward and backward with Migrate, Up, Down, Rollback, MigrateTo, Redo and Status. Every migration runs in its own transaction, so a failure rolls back cleanly and re-running is idempotent. Migrations register programmatically or load from a directory / io/fs.FS of <version>_<name>.up.sql / .down.sql pairs, and a tiny schema DSL (CreateTable, AddColumn, AddIndex, typed column helpers, foreign keys) emits predictable, greppable ANSI SQL.
Install
$ go get github.com/malcolmston/migrateQuick start
import "github.com/malcolmston/migrate"
mg := migrate.New(db) // any database/sql *sql.DB
mg.Register(migrate.Migration{
Version: 20240101,
Name: "create_users",
UpSQL: migrate.CreateTable("users", func(t *migrate.Table) {
t.String("email", migrate.NotNull(), migrate.Unique())
t.Timestamps()
}),
DownSQL: migrate.DropTable("users"),
})
if err := mg.Migrate(context.Background()); err != nil {
log.Fatal(err)
}Features
- Versioned, reversible migrations — a
Migrationwith auint64Version, applied ascending and rolled back descending - Go or SQL directions —
Up/Downasfunc(ctx, *sql.Tx) error, orUpSQL/DownSQLraw text - Transaction per migration — a failure rolls back, does not record the version, and halts; re-running
Migrateis idempotent - Full command set —
Migrate,Up,Down,Rollback,MigrateTo,RedoandStatuson theMigrator - File loading —
LoadDirandLoadFSread<version>_<name>.up.sql/.down.sqlpairs from anyio/fs.FS - Schema DSL —
CreateTablewith typed helpers (String,Text,Integer,Boolean,Timestamps) plusAddColumn,AddIndex,DropTable,RenameColumn - Rails-style references & foreign keys —
Table.ReferenceswithWithForeignKey,ReferenceNotNullandReferenceTable - Zero dependencies — pure Go standard library over
database/sql, no cgo, nothing to audit but the toolchain