go-migrationGo Migration
Package Reference
Documentation

Migrator

Complete package reference for the go-migration Migrator — all public methods with signatures, parameters, return types, and usage examples.

Migrator API

The Migrator is the central component of go-migration. It manages migration registration, execution, rollback, and status tracking.

Import path: github.com/gopackx/go-migration/pkg/migrator

For conceptual documentation, see Migrations.


migrator.Run()

The all-in-one CLI runner. Handles argument parsing, config loading (migration.json with ${ENV} interpolation, falls back to go-migration.yaml), database connection, auto-discovery of migrations and seeders, grammar auto-resolution from driver name, and command dispatch.

go
func Run()

This function does not return — it calls os.Exit() on completion or error.

main.go
package main

import (
    "github.com/gopackx/go-migration/pkg/migrator"
    _ "your-project/database/migrations"
    _ "your-project/database/seeders"
)

func main() {
    migrator.Run()
}

Run() performs the following steps:

  1. Parses CLI arguments to determine the command
  2. For commands that need a database (smart classification skips DB for help, init, make:*):
    • Loads migration.json (or --config path) with ${ENV} variable interpolation. Falls back to go-migration.yaml for backward compatibility.
    • Opens a database connection using the config
    • Auto-discovers all registered migrations and seeders
    • Resolves the grammar from the driver field (postgres → PostgreSQL, mysql → MySQL, sqlite → SQLite)
  3. Dispatches the command

See Quick Start for a complete example.

New in v1.0.0: Run() now supports the --dry-run flag on the migrate commands, the --tag flag on db:seed, the --force flag on migrate:reset, and the new db:seed:rollback and db:seed:truncate commands. See CLI Reference for details.

New in v1.0.0: Run() now loads migration.json as the default configuration file (previously go-migration.yaml). Internally, cobra has been replaced by a custom Router built on a map[string]CommandHandler and the standard library flag package. The public API (migrator.New(), migrator.Run(), the Migration interface) is unchanged.


migrator.New()

Creates a new Migrator instance bound to a database connection.

go
func New(db *sql.DB, opts ...Option) *Migrator
ParameterTypeDescription
db*sql.DBThe database connection to run migrations against
opts...OptionOptional configuration (e.g., WithGrammar)

Returns: *Migrator

go
import (
    "database/sql"
    "github.com/gopackx/go-migration/pkg/migrator"
    "github.com/gopackx/go-migration/pkg/schema/grammars"
)

// Default (no grammar configured; required for Fresh())
m := migrator.New(db)

// With a specific grammar
m := migrator.New(db, migrator.WithGrammar(&grammars.MySQLGrammar{}))

Available options:

OptionSignatureDescription
WithGrammarWithGrammar(g schema.Grammar) OptionSets the SQL grammar (required for Fresh())
WithTableNameWithTableName(name string) OptionSets the tracking table name (default: "migrations")
WithLoggerWithLogger(l Logger) OptionSets the logger used by the migrator and runner
WithAutoDiscoverWithAutoDiscover() OptionLoads auto-registered migrations during construction
WithProgressWithProgress(fn ProgressFunc) OptionRegisters a per-migration progress callback
WithDryRunWithDryRun(w io.Writer) OptionEnables dry-run mode, writing SQL to w instead of executing

WithGrammar accepts any value implementing schema.Grammar. The grammars package provides &grammars.MySQLGrammar{}, &grammars.PostgresGrammar{}, and &grammars.SQLiteGrammar{} (or the matching grammars.NewMySQLGrammar(), grammars.NewPostgresGrammar(), and grammars.NewSQLiteGrammar() constructors).

The Logger interface required by WithLogger is:

go
type Logger interface {
    Info(msg string, args ...any)
    Error(msg string, args ...any)
}
go
// Custom table name and logger
m := migrator.New(db,
    migrator.WithGrammar(&grammars.PostgresGrammar{}),
    migrator.WithTableName("schema_migrations"),
    migrator.WithLogger(myLogger),
)

// Dry-run: print SQL to stdout instead of executing
m := migrator.New(db,
    migrator.WithGrammar(&grammars.PostgresGrammar{}),
    migrator.WithDryRun(os.Stdout),
)

See Database Grammars for grammar selection details.


migrator.AutoRegister()

Registers a migration in the global auto-registry. Intended to be called from init() functions in migration files.

go
func AutoRegister(name string, m Migration)
ParameterTypeDescription
namestringMigration name matching YYYYMMDDHHMMSS_description format
mMigrationPointer to a struct implementing the Migration interface

Panics if the name is invalid or a duplicate — fail-fast at startup.

migrations/20240101000001_create_users.go
package migrations

import "github.com/gopackx/go-migration/pkg/migrator"

func init() {
    migrator.AutoRegister("20240101000001_create_users", &CreateUsersTable{})
}

AutoRegister panics instead of returning an error because init() functions cannot return errors. This ensures configuration mistakes are caught immediately at startup.

See Registering Migrations for the full auto-discovery pattern.


migrator.GetAutoRegistered()

Returns all auto-registered migrations in timestamp-sorted order.

go
func GetAutoRegistered() []registeredMigration

Returns: []registeredMigration — a defensive copy of the auto-registry contents.


migrator.ResetAutoRegistry()

Clears the global auto-registry. Intended for testing only.

go
func ResetAutoRegistry()

migrator.WithAutoDiscover()

Returns an Option that loads all auto-registered migrations into the Migrator during construction.

go
func WithAutoDiscover() Option

Panics if a name conflict exists between auto-registered and manually registered migrations.

go
m := migrator.New(db, migrator.WithAutoDiscover())

See Registering Migrations for usage details.


migrator.WithProgress()

Returns an Option that registers a callback function to receive progress events during migration execution.

go
type ProgressEvent struct {
    Name      string
    Index     int
    Total     int
    Duration  time.Duration
    Direction string
}

type ProgressFunc func(event ProgressEvent)

func WithProgress(fn ProgressFunc) Option
FieldTypeDescription
NamestringThe migration name being executed
IndexintThe 0-based index of the current migration
TotalintThe total number of migrations to execute
Durationtime.DurationHow long this migration took to execute
DirectionstringEither "up" or "down"

The callback is invoked after each migration completes, giving you real-time visibility into the migration process.

go
m := migrator.New(db, migrator.WithProgress(func(e migrator.ProgressEvent) {
    // Index is 0-based; add 1 for human-friendly "N of Total" display.
    fmt.Printf("[%d/%d] %s %s (%s)\n", e.Index+1, e.Total, e.Direction, e.Name, e.Duration)
}))

See Progress Reporting.


m.Register()

Registers a migration struct with the migrator under a unique name.

go
func (m *Migrator) Register(name string, migration Migration) error
ParameterTypeDescription
namestringUnique migration name (must match the timestamp-prefixed format)
migrationMigrationPointer to a struct implementing the Migration interface

Returns: errornil on success, or an error wrapping ErrInvalidMigrationName (bad name format) or ErrDuplicateMigration (name already registered).

go
if err := m.Register("20240101000001_create_users_table", &migrations.CreateUsersTable{}); err != nil {
    log.Fatal(err)
}
if err := m.Register("20240115000001_create_posts_table", &migrations.CreatePostsTable{}); err != nil {
    log.Fatal(err)
}

Migration names are sorted to determine execution order. Use a 14-digit YYYYMMDDHHMMSS_description prefix (or the YYYY_MM_DD_HHMMSS_RRRR_description form) for chronological ordering. The description must be lowercase.

See Registering Migrations for naming conventions and auto-discovery.


m.AutoDiscover()

Loads all migrations from the global auto-registry into the Migrator's internal registry.

go
func (m *Migrator) AutoDiscover() error

Returns: error — returns nil on success, or an error wrapping ErrDuplicateMigration if a name conflict exists with manually registered migrations.

go
m := migrator.New(db)
if err := m.AutoDiscover(); err != nil {
    log.Fatal(err)
}

For most cases, use WithAutoDiscover() option instead of calling AutoDiscover() directly. The option handles errors by panicking, which is appropriate during initialization.

See Registering Migrations for the full auto-discovery workflow.


m.Up()

Executes all pending (not yet run) migrations in alphabetical order.

go
func (m *Migrator) Up() error

Returns: error — returns nil on success, or the first error encountered.

go
if err := m.Up(); err != nil {
    log.Fatal(err)
}

All migrations executed in a single Up() call are assigned the same batch number. Calling Up() multiple times is safe — already-executed migrations are skipped.

See Running Migrations for execution details and Batch Tracking for batch behavior.


m.Rollback()

Rolls back migrations by batch or by step count.

go
func (m *Migrator) Rollback(steps int) error
ParameterTypeDescription
stepsint0 to roll back the last batch, or a positive integer for step-based rollback

Returns: error

go
// Roll back the last batch
if err := m.Rollback(0); err != nil {
    log.Fatal(err)
}

// Roll back the last 3 migrations
if err := m.Rollback(3); err != nil {
    log.Fatal(err)
}

See Rollback for detailed examples.


m.Reset()

Rolls back all executed migrations in reverse order by calling each migration's Down method.

go
func (m *Migrator) Reset() error

Returns: error

go
if err := m.Reset(); err != nil {
    log.Fatal(err)
}

Reset() is destructive — all data in migrated tables will be lost.

See Reset, Refresh & Fresh.


m.Refresh()

Rolls back all migrations and then re-runs them. Equivalent to Reset() followed by Up().

go
func (m *Migrator) Refresh() error

Returns: error

go
if err := m.Refresh(); err != nil {
    log.Fatal(err)
}

See Reset, Refresh & Fresh.


m.Fresh()

Drops all tables in the database and runs all migrations from scratch. Does not call Down methods.

go
func (m *Migrator) Fresh() error

Returns: error

go
if err := m.Fresh(); err != nil {
    log.Fatal(err)
}

Fresh() drops every table in the database, including the migrations tracking table. Never use on production.

See Reset, Refresh & Fresh.


m.Status()

Returns the current state of all registered migrations.

go
func (m *Migrator) Status() ([]MigrationStatus, error)

Returns: []MigrationStatus, error

Each MigrationStatus contains:

FieldTypeDescription
NamestringThe migration name
AppliedboolWhether the migration has been applied
BatchintThe batch number (0 if not yet applied)
AppliedAt*time.TimeWhen the migration was applied (nil if not yet applied)
go
statuses, err := m.Status()
if err != nil {
    log.Fatal(err)
}

for _, s := range statuses {
    fmt.Printf("%s — Applied: %v, Batch: %d\n", s.Name, s.Applied, s.Batch)
}

See Migration Status.


m.BeforeMigrate()

Registers a hook that runs before each migration is executed. The hook fires once per migration, receiving that migration's name and direction.

go
func (m *Migrator) BeforeMigrate(fn func(name string, direction string) error)
ParameterTypeDescription
fnfunc(name string, direction string) errorCallback executed before each migration. direction is "up" or "down".

If the callback returns an error, that migration is aborted and no further migrations run.

go
m.BeforeMigrate(func(name, direction string) error {
    log.Printf("Starting %s %s...", direction, name)
    return nil
})

See Hooks for use cases and error behavior.


m.AfterMigrate()

Registers a hook that runs after each migration completes. The hook fires once per migration, receiving its name, direction, and execution duration.

go
func (m *Migrator) AfterMigrate(fn func(name string, direction string, duration time.Duration) error)
ParameterTypeDescription
fnfunc(name string, direction string, duration time.Duration) errorCallback executed after each migration. direction is "up" or "down".

If the callback returns an error, the error is ignored and execution continues.

go
m.AfterMigrate(func(name, direction string, duration time.Duration) error {
    log.Printf("Finished %s %s in %s", direction, name, duration)
    return nil
})

See Hooks for use cases and error behavior.


Migration Interface

Structs registered with the migrator must implement this interface:

go
type Migration interface {
    Up(s *schema.Builder) error
    Down(s *schema.Builder) error
}
MethodDescription
Up(*schema.Builder) errorDefines the forward migration
Down(*schema.Builder) errorDefines the reverse migration

Optionally implement TransactionOption to opt out of per-migration transaction wrapping. Return true to disable the surrounding transaction:

go
type TransactionOption interface {
    DisableTransaction() bool
}

See Defining Migrations and Transactions.


TaggedSeeder Interface

New in v1.0.0

Seeders can implement TaggedSeeder to be selectively run using the --tag flag on db:seed.

go
type TaggedSeeder interface {
    Tags() []string
}
MethodDescription
Tags() []stringReturns the tags this seeder belongs to
seeders/user_seeder.go
type UserSeeder struct{}

func (s *UserSeeder) Run(db *sql.DB) error { /* ... */ }
func (s *UserSeeder) Tags() []string { return []string{"core"} }
bash
# Run only seeders tagged "core"
go-migration db:seed --tag=core

See Seeder Tags for details.


RollbackableSeeder Interface

New in v1.0.0

Seeders can implement RollbackableSeeder to support rollback via the db:seed:rollback command.

go
type RollbackableSeeder interface {
    Rollback(db *sql.DB) error
}
MethodDescription
Rollback(*sql.DB) errorReverses the seeder's Run operation
seeders/user_seeder.go
type UserSeeder struct{}

func (s *UserSeeder) Run(db *sql.DB) error { /* ... */ }

func (s *UserSeeder) Rollback(db *sql.DB) error {
    _, err := db.Exec("DELETE FROM users WHERE seeded = true")
    return err
}
bash
go-migration db:seed:rollback --class=UserSeeder

See Seeder Rollback for details.


Quick Reference

MethodSignatureDescription
RunRun()All-in-one CLI runner (config, DB, auto-discover, dispatch)
NewNew(db, ...Option) *MigratorCreate a new migrator
AutoRegisterAutoRegister(name, migration)Register a migration via init()
WithAutoDiscoverWithAutoDiscover() OptionOption to load auto-registered migrations
WithProgressWithProgress(fn) OptionOption to receive per-migration progress events
RegisterRegister(name, migration) errorRegister a migration manually
AutoDiscoverAutoDiscover() errorLoad auto-registered migrations
UpUp() errorRun pending migrations
RollbackRollback(steps) errorRoll back migrations
ResetReset() errorRoll back all migrations
RefreshRefresh() errorReset + Up
FreshFresh() errorDrop all tables + Up
StatusStatus() ([]MigrationStatus, error)Get migration states
BeforeMigrateBeforeMigrate(fn)Register per-migration pre-hook
AfterMigrateAfterMigrate(fn)Register per-migration post-hook
TaggedSeederTags() []stringInterface for tag-based seeder filtering (v1.0.0)
RollbackableSeederRollback(db) errorInterface for seeder rollback support (v1.0.0)