Migrations
Version-controlled database schema changes with up/down functions.
Migrations let you evolve your database schema over time with version-controlled Go functions.
Creating a Migration
go run cmd/main.go make:migration create_posts_table
# Creates: database/migrations/YYYYMMDDHHMMSS_create_posts_table.go
Migration Structure
Each migration file registers itself in init():
package migrations
import "gorm.io/gorm"
func init() {
Register(Migration{
Version: "20260101120000_create_posts_table",
Up: func(db *gorm.DB) error {
type Post struct {
ID uint `gorm:"primaryKey"`
Title string `gorm:"size:255;not null"`
Body string `gorm:"type:text"`
UserID uint
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
return db.AutoMigrate(&Post{})
},
Down: func(db *gorm.DB) error {
return db.Migrator().DropTable("posts")
},
})
}
Running Migrations
# Apply all pending migrations
go run cmd/main.go migrate
# Rollback the last batch
go run cmd/main.go migrate:rollback
# Check migration status
go run cmd/main.go migrate:status
How It Works
- Migrations are tracked in a
schema_migrationstable with version, batch number, and timestamp - Each
migraterun applies all pending migrations in a new batch migrate:rollbackundoes the last batch by runningDownfunctions in reverse ordermigrate:statusshows which migrations have been applied and which are pending