A powerful, type-safe Go migration framework with plugin architecture. Build reliable database migrations with the full power of Go.
- π Plugin Architecture: Support multiple databases through plugins
- π‘οΈ Type Safety: Leverage Go's type system for reliable migrations
- π― Programmable: Write migrations in Go with full language features
- β‘ Performance: Fast execution with minimal overhead
- π§ Flexible: Customize behavior through configuration
- π Tracking: Built-in migration state management
Unlike traditional SQL-based migration tools, Gomiger lets you:
- Use Go's powerful standard library and ecosystem
- Write complex data transformations with loops, conditions, and functions
- Leverage existing Go libraries and business logic
- Maintain type safety throughout your migrations
- Test your migrations like regular Go code
- Go 1.21 or later
- Database (MongoDB, PostgreSQL, etc.)
Option 1: Go Install (Recommended)
go install github.com/ParteeLabs/gomiger/core/cmd/gomiger-init@latestOption 2: Manual Installation
go get github.com/ParteeLabs/gomiger/core
go get github.com/ParteeLabs/gomiger/mongomiger # For MongoDB
go get github.com/urfave/cli/v3 # For CLI supportStep 2: Add the gomiger.rc.yaml file to the root of your project.
path: './migrations' # Path to the migrations folder
pkg_name: 'mgr' # Package name
schema_store: '' # Database schema storeStep 3: Initialize the source code by running:
go run github.com/ParteeLabs/gomiger/core/cmd/gomiger-initThe source code will be initialized in the path folder.
migrations/
βββ cli.mg.go
βββ migrator.mg.go
Step 4: Add you CLI entry point.
You can add any entry point (e.g. cli.go or gomiger.go) then import & call the Run function in cli.mg.go
// cli.go
package main
import (
mgr "test/migrations"
)
func main() {
mgr.Run()
}Gomiger supports multiple databases through plugins:
go get github.com/ParteeLabs/gomiger/mongomigerAdd to your migrator.mg.go:
type Migrator struct {
- core.BaseMigrator
+ *mongomiger.Mongomiger
Config *core.GomigerConfig
}
func NewMigrator(config *core.GomigerConfig) core.Gomiger {
return &Migrator{
+ Mongomiger: mongomiger.NewMongomiger(config),
Config: config,
}
}Coming Soon - We're working on PostgreSQL support!
Want to add support for your database? Check our Plugin Development Guide.
Generate a new migration file.
go run cli.go new migration_nameRun migrations up.
export GOMIGER_URI="mongodb://localhost:27017"
go run cli.go up # To run all migrations
go run cli.go up version # To stop at a specific versionRun migrations down.
export GOMIGER_URI="mongodb://localhost:27017"
go run cli.go down version// migrations/202410151200_add_users.mg.go
package mgr
import (
"context"
"go.mongodb.org/mongo-driver/v2/bson"
)
func (m *Migrator) Migration_202410151200_add_users_Up(ctx context.Context) error {
// Create users collection with validation
validator := bson.M{
"$jsonSchema": bson.M{
"bsonType": "object",
"required": []string{"email", "created_at"},
"properties": bson.M{
"email": bson.M{
"bsonType": "string",
"description": "must be a string and is required",
},
"created_at": bson.M{
"bsonType": "date",
"description": "must be a date and is required",
},
},
},
}
opts := options.CreateCollection().SetValidator(validator)
return m.Db.CreateCollection(ctx, "users", opts)
}
func (m *Migrator) Migration_202410151200_add_users_Down(ctx context.Context) error {
return m.Db.Collection("users").Drop(ctx)
}// migrations/202410151300_migrate_user_format.mg.go
package mgr
import (
"context"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
func (m *Migrator) Migration_202410151300_migrate_user_format_Up(ctx context.Context) error {
collection := m.Db.Collection("users")
// Find all users with old format
cursor, err := collection.Find(ctx, bson.M{"full_name": bson.M{"$exists": true}})
if err != nil {
return err
}
defer cursor.Close(ctx)
// Transform each user
for cursor.Next(ctx) {
var user bson.M
if err := cursor.Decode(&user); err != nil {
return err
}
// Split full_name into first_name and last_name
if fullName, ok := user["full_name"].(string); ok {
names := strings.Fields(fullName)
update := bson.M{
"$set": bson.M{
"first_name": names[0],
"last_name": "",
"updated_at": time.Now(),
},
"$unset": bson.M{"full_name": ""},
}
if len(names) > 1 {
update["$set"].(bson.M)["last_name"] = strings.Join(names[1:], " ")
}
_, err := collection.UpdateOne(ctx, bson.M{"_id": user["_id"]}, update)
if err != nil {
return err
}
}
}
return cursor.Err()
}Gomiger follows a clean plugin architecture:
βββββββββββββββββββ ββββββββββββββββββββ
β Your App ββββββ Gomiger Core β
βββββββββββββββββββ ββββββββββββββββββββ
β
βββββββββββΌββββββββββ
β β
βββββββββΌβββββ βββββββββββΌβββββ
β MongoDB β β PostgreSQL β
β Plugin β β Plugin β
ββββββββββββββ ββββββββββββββββ
- Core: Migration engine and interfaces
- Plugins: Database-specific implementations
- Generated Code: Type-safe migration scaffolding
- CLI: Command-line interface for operations
export GOMIGER_URI="mongodb://localhost:27017/mydb"# gomiger.rc.yaml
path: './migrations'
pkg_name: 'mgr'
schema_store: 'schema_migrations'// migrations_test.go
func TestUserMigration(t *testing.T) {
config := &core.GomigerConfig{
URI: "mongodb://localhost:27017/test_db",
SchemaStore: "test_schemas",
}
migrator := NewMigrator(config)
ctx := context.Background()
// Test up migration
err := migrator.Up(ctx, "202410151200")
assert.NoError(t, err)
// Verify collection exists
collections, err := migrator.Db.ListCollectionNames(ctx, bson.D{})
assert.NoError(t, err)
assert.Contains(t, collections, "users")
// Test down migration
err = migrator.Down(ctx, "202410151200")
assert.NoError(t, err)
}- Getting Started Guide
- Plugin Development
- Best Practices
- Project Roadmap πΊοΈ
- API Reference
- Examples Repository
We welcome contributions! Please see our Contributing Guide for details.
git clone https://github.com/ParteeLabs/gomiger.git
cd gomiger
go work use ./core ./mongomiger ./examples
go test ./...This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by Sequelize Umzug
- Built with the amazing Go ecosystem
- Special thanks to all contributors
Made with β€οΈ by ParteeLabs