smf is a lightweight CLI tool for diffing database schemas from SQL dumps and generating (SQL) migration with breaking-change warnings and rollback.
It is intentionally config-free: you give it two schema files (old.sql, new.sql), it shows what changed and produces a migration script, as well as rollback.
smf is always in safe mode first, which means it won't drop table, or apply changes that can potentially result in data loss.
- Supported dialects: MySQL with TiDB options (diff + migration generation + apply on your database)
This repository currently uses a local Go module name (module smf), so the simplest workflow is building from source:
go build -o smf ./Run directly:
go run . --helpRun tests:
go test ./..../smf diff <old.sql> <new.sql>
./smf diff <old.sql> <new.sql> -o diff.txtTip: there are ready-to-use fixture, so you can test the behavior:
./smf diff test/data/mysql_schema_v1.sql test/data/mysql_schema_v2.sql./smf migrate <old.sql> <new.sql>
./smf migrate <old.sql> <new.sql> -o migration.sqlBy default, smf runs in safe mode (non-destructive where possible):
- dropped tables are renamed to
__smf_backup_*instead ofDROP TABLE - dropped columns are renamed to
__smf_backup_*instead ofDROP COLUMN
To allow destructive changes, pass --unsafe:
./smf migrate <old.sql> <new.sql> --unsafe -o migration.sqlsmf can emit rollback SQL for the generated migration (to run separately):
./smf migrate <old.sql> <new.sql> -o migration.sql -r rollback.sqlRollback generation is "best-effort". For example, a true DROP TABLE cannot be automatically restored without an external backup. Maybe we will do something for it later.
The generator annotates output with warnings/breaking changes for schema operations such as:
- table/column drops (data loss)
- type changes (widening vs narrowing) and risky length shrinks
NULL->NOT NULLtransitions and addingNOT NULLcolumns without defaults- constraint/index additions/removals/modifications (PK/UK/FK/CHECK)
- charset/collation changes (table + column)
- heuristics for likely column renames (to preserve data via
CHANGE COLUMN)
- smf operates on SQL schema dumps (DDL). It does not inspect live DB data.
We welcome contributions! Please see CONTRIBUTING.md for guidelines on how to get started, our coding standards, and how to run tests.
- Core diff logic lives under
internal/diff/. - Dialect-specific generation lives under
internal/dialect/(MySQL implementation ininternal/dialect/mysql/). - Parser integration lives under
internal/parser/.
If you add new behavior, please add/extend tests and prefer fixture-based regression tests.