A Go utility that replicates Django's makemigrations functionality for PostgreSQL databases by collecting and merging schema.sql files from Go modules and generating Goose migrations.
- Scan direct dependencies from
go.mod - Look for
sql/schema.sqlfiles in each dependency - Optionally check for
-- MIGRATION_SCHEMAmarker on first line - Collect all discovered schema files
- Concatenate all discovered schema files into a single unified schema
- Handle table merging when multiple modules define the same table
- Conflict resolution rules:
- VARCHAR fields: larger size wins (255 over 100)
- NULL constraints: NOT NULL wins over nullable
- Other conflicts: implement sensible defaults
- Analyze foreign key relationships
- Topologically sort tables to ensure correct creation order
- Handle circular dependencies gracefully
- Tables and columns
- Indexes (handle duplicates and naming conflicts)
- Constraints (primary key, foreign key, unique, check)
- Triggers and functions
- Sequences and custom types
- Schema namespaces
- Compare current merged schema against last recorded schema
- Generate Goose-compatible migration files
- Store in
migrations/directory - Use Goose naming convention (e.g.,
00001_add_users_table.sql) - Generate both UP and DOWN migrations
- Auto-generate meaningful descriptions based on changes
- Store last complete merged schema in migrations directory
- Use well-known filename that Goose ignores (e.g.,
migrations/.schema_snapshot.sql) - Update snapshot after successful migration generation
- Add
-- REVIEWcomment to destructive operations (DROP, DELETE) - Validate schema syntax before generating migrations
- Detect and warn about potential data loss
# First time setup - initialize migrations directory
makemigrations init [flags]
# Default behavior (runs makemigrations_sql)
makemigrations [flags]
# Explicit subcommand
makemigrations makemigrations_sql [flags]--dry-run- Show what would be generated without creating files--name <name>- Override auto-generated migration name--check- Exit with error code if migrations are needed (for CI/CD)--verbose- Show detailed processing information--help- Display help information
github.com/stripe/pg-schema-diff- For schema comparison and diff generationgithub.com/pressly/goose- For migration file format compatibility- Go standard library for module parsing and file operations
-
Module Scanner
- Parse go.mod for direct dependencies
- Locate and read schema.sql files
- Validate schema markers
-
Schema Merger
- Parse SQL statements
- Identify and merge duplicate table definitions
- Apply conflict resolution rules
- Maintain element metadata (source module, line numbers)
-
Dependency Analyzer
- Build dependency graph from foreign keys
- Perform topological sort
- Detect circular references
-
Diff Engine
- Load previous schema snapshot
- Compare with current merged schema
- Generate migration statements
- Create rollback statements
-
Migration Writer
- Format according to Goose conventions
- Generate descriptive names
- Add safety comments
- Write to migrations directory
-- +goose Up
-- +goose StatementBegin
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
-- +goose StatementEnd-- +goose Down
-- +goose StatementBegin
-- REVIEW
DROP INDEX IF EXISTS idx_users_email;
-- REVIEW
DROP TABLE IF EXISTS users;
-- +goose StatementEnd- No go.mod file found
- Invalid SQL syntax in schema files
- Unresolvable circular dependencies
- File system write failures
- Destructive operations detected
- Potential data type incompatibilities
- Missing schema markers (when expected)
- Naming conflicts in indexes/constraints
- Successfully merges schemas from multiple modules
- Generates valid Goose migrations
- Handles complex PostgreSQL schemas
- Provides clear error messages
- Maintains migration history accurately
- Support for custom merge strategies
- Integration with CI/CD pipelines
- Schema validation rules
- Migration squashing
- Rollback verification
- Support for other SQL databases
- Developer adds/modifies
sql/schema.sqlin their module - Run
makemigrations - Utility scans dependencies and merges schemas
- Compares with last snapshot
- Generates migration file
migrations/00002_add_orders_table.sql - Updates schema snapshot
- Developer reviews migration (especially
-- REVIEWsections) - Run
goose upto apply migration
Consider adding .makemigrations.yaml for:
- Custom schema file locations
- Module inclusion/exclusion rules
- Conflict resolution overrides
- Custom naming conventions