Migration Status
Check which migrations have run and their batch numbers using m.Status().
Migration Status
Use m.Status() to inspect the current state of all registered migrations — which ones have run, their batch numbers, and which are still pending.
Using m.Status()
statuses, err := m.Status()
if err != nil {
log.Fatal(err)
}
for _, s := range statuses {
fmt.Printf("Migration: %s | Applied: %v | Batch: %d\n", s.Name, s.Applied, s.Batch)
}m.Status() returns a []migrator.MigrationStatus, one entry for each registered migration.
Read-Only Behavior
m.Status() never writes to the database:
- It does not create the tracking table. If the table does not exist yet, every registered migration is reported as pending.
- It does not take the migration lock, so it never waits for a running migration.
This makes it safe to call from health checks, readiness probes, or a separate monitoring process.
Before v1.2.0, m.Status() created the tracking table if it was missing. It is now strictly read-only.
Status Output
Each status entry contains:
| Field | Type | Description |
|---|---|---|
Name | string | The migration name as passed to m.Register() |
Applied | bool | Whether the migration has been applied |
Batch | int | The batch number (0 if not yet applied) |
AppliedAt | *time.Time | When the migration was applied (nil if not yet applied) |
Example Output
Given these registered migrations:
m.Register("20240101000001_create_users_table", &migrations.CreateUsersTable{})
m.Register("20240115000001_create_posts_table", &migrations.CreatePostsTable{})
m.Register("20240201000001_add_phone_to_users", &migrations.AddPhoneToUsers{})If the first two have been applied, m.Status() produces:
Migration: 20240101000001_create_users_table | Applied: true | Batch: 1
Migration: 20240115000001_create_posts_table | Applied: true | Batch: 1
Migration: 20240201000001_add_phone_to_users | Applied: false | Batch: 0Complete Example
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
"github.com/gopackx/go-migration/pkg/migrator"
"github.com/gopackx/go-migration/pkg/schema/grammars"
"your-project/migrations"
)
func main() {
db, err := sql.Open("postgres", "postgres://user:password@localhost:5432/mydb?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
m := migrator.New(db, migrator.WithGrammar(grammars.NewPostgresGrammar()))
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)
}
if err := m.Register("20240201000001_add_phone_to_users", &migrations.AddPhoneToUsers{}); err != nil {
log.Fatal(err)
}
statuses, err := m.Status()
if err != nil {
log.Fatal(err)
}
fmt.Println("Migration Status:")
fmt.Println("─────────────────────────────────────────────────────")
for _, s := range statuses {
status := "Pending"
if s.Applied {
status = fmt.Sprintf("Applied (Batch %d)", s.Batch)
}
fmt.Printf(" %s — %s\n", s.Name, status)
}
}m.Status() only reports on migrations that are registered with the migrator. If a migration was previously run but is no longer registered, it won't appear in the status output.
Checking for Pending Migrations from the CLI
The migrate:status command prints the same information as a table. Add --check to exit with status 1 (after printing the table, and with N migration(s) pending on stderr) when anything is pending — useful as a CI step or as a readiness gate that waits for a migration Job to finish:
go-migration migrate:status --check
# Block until every migration has been applied
until go-migration migrate:status --check; do sleep 5; doneIn your own code, the equivalent is to count the entries with Applied == false:
pending := 0
for _, s := range statuses {
if !s.Applied {
pending++
}
}
if pending > 0 {
log.Fatalf("%d migration(s) pending", pending)
}See Concurrency and Locking for a Kubernetes example.
What's Next?
- Running Migrations — execute pending migrations
- Rollback — undo migrations when needed