gorm-migrate

module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2025 License: MIT

README

GORM Migrate - Migration Tool

CI Go Report Card Go Version License

Automatically generate database migrations from your GORM models by comparing them with the current database schema.

Features

  • Generate migrations automatically by comparing your GORM models with the database
  • Only creates migrations when there are actual schema differences
  • Handles case-insensitive table and column names correctly
  • Reduces false positives through proper type normalization (e.g., int/bigint/integer are treated as equivalent)

Quick Start

1. Install
go get -u github.com/beesaferoot/gorm-migrate@latest
2. Set up environment
export DATABASE_URL="postgresql://user:pass@localhost:5432/your_db"
3. Create your migration binary

Create cmd/migration/main.go in your project:

package main

import (
    "your-project/models" // Import your models package
    "github.com/spf13/cobra"
    "github.com/joho/godotenv"
    "github.com/beesaferoot/gorm-migrate/migration"
    "github.com/beesaferoot/gorm-migrate/migration/commands"
)

// Simple registry implementation
type MyModelRegistry struct{}

func (r *MyModelRegistry) GetModels() map[string]interface{} {
    return models.ModelTypeRegistry // Your registry
}

func init() {
    migration.GlobalModelRegistry = &MyModelRegistry{}
}

func main() {
    _ = godotenv.Load() // optionally load environment file
    rootCmd := &cobra.Command{
        Use:   "migration",
        Short: "Database Migration Tool",
    }

    rootCmd.AddCommand(
        commands.RegisterCmd(),
        commands.InitCmd(),
        commands.CreateCmd(),
        commands.GenerateCmd(),
        commands.UpCmd(),
        commands.DownCmd(),
        commands.StatusCmd(),
        commands.HistoryCmd(),
        commands.ValidateCmd(),
    )

    if err := rootCmd.Execute(); err != nil {
        panic(err)
    }
}
4. Generate your model registry

Use the register command to automatically scan your models directory (e.g., models/) and generate a models_registry.go file.

go run cmd/migration/main.go register [path/to/models]

This command creates a standard Go file that you can review and even edit if needed. It will look something like this:

package models

var ModelTypeRegistry = map[string]interface{}{
    "User":    User{},
    "Post":    Post{},
    "Comment": Comment{},
    // Add all your models here
}
5. Initialize and generate migrations
go run cmd/migration/main.go init
go run cmd/migration/main.go register [path/to/models]
go run cmd/migration/main.go generate init_db
go run cmd/migration/main.go up

Usage

# Initialize migration system
go run cmd/migration/main.go init

# Generate migration from model changes
go run cmd/migration/main.go generate <name>

# Apply migrations
go run cmd/migration/main.go up

# Rollback last migration
go run cmd/migration/main.go down

# Check status
go run cmd/migration/main.go status

Example

Your GORM model:

type User struct {
    gorm.Model
    Name  string
    Email string `gorm:"uniqueIndex"`
}

Generated migration:

package migrations

import (
    "github.com/beesaferoot/gorm-migrate/migration"
    "gorm.io/gorm"
    "time"
)

func init() {
    migration.RegisterMigration(&migration.Migration{
        Version:   "20250620232804",
        Name:      "init_db",
        CreatedAt: time.Now(),
        Up: func(db *gorm.DB) error {
            if err := db.Exec(`CREATE TABLE "users" (
    id BIGSERIAL PRIMARY KEY,
    created_at timestamp,
    updated_at timestamp,
    deleted_at timestamp,
    name varchar(255),
    email varchar(255)
);`).Error; err != nil {
                return err
            }
            if err := db.Exec(`CREATE UNIQUE INDEX idx_users_email ON "users"(email);`).Error; err != nil {
                return err
            }
            return nil
        },
        Down: func(db *gorm.DB) error {
            if err := db.Exec(`DROP TABLE IF EXISTS "users";`).Error; err != nil {
                return err
            }
            return nil
        },
    })
}

Environment Variables

Variable Description Required
DATABASE_URL PostgreSQL connection string Yes
MIGRATIONS_PATH Path for migration files No (default: ./migrations)

Testing

Run All Tests
make test
Run Tests with Coverage
go test -v -coverprofile=coverage.out ./tests/...
go tool cover -func=coverage.out
Run Specific Test Packages
# Run diff tests
go test ./tests/migration/diff/...

# Run command tests
go test ./tests/migration/...

# Run with verbose output
go test -v ./tests/...
Run Linters
make lint

Limitations

  • Schema comparison is model-driven.
    • Only columns present in your Go models are considered for schema diffs. Any manual changes to the database schema that are not reflected in your models will not be detected.

If you require support for these features, please open an issue or contribute to the project.

License

MIT License - see LICENSE file for details.

Directories

Path Synopsis
cmd
gorm-migrate command
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL