// the find
pressly/goose
A database migration tool. Supports SQL migrations and Go functions.
goose is a battle-tested database migration tool for Go that works as both a CLI and an embeddable library. It handles SQL and Go-function migrations across a wide range of databases (Postgres, MySQL, SQLite, ClickHouse, MSSQL, Spanner, and more). It's aimed at Go teams who want migrations to live alongside application code and be runnable at startup or via CI.
- The Provider API (provider.go) is a proper non-global interface, which means you can have multiple goose instances with different configs in the same binary — a real improvement over the old global state approach that still exists as a compatibility layer.
- embed.FS support is well-integrated, letting you ship migrations baked into your binary without any filesystem assumptions at runtime.
- The `-- +goose StatementBegin/End` annotation system correctly handles PL/pgSQL and other multi-statement blocks that would otherwise break naive semicolon splitting.
- Build tags for stripping unused drivers (no_postgres, no_mysql, etc.) meaningfully reduce binary size, which matters when shipping a migration tool as a sidecar or init container.
- Two APIs exist side-by-side: the old global functions (goose.Up, goose.SetDialect, etc.) and the newer Provider struct. The README leads with the old global API in most examples, so newcomers are likely to write code against the deprecated path without realizing it.
- Go migrations rely on init() registration with a global registry, which causes problems if you need isolated test environments or want to run migrations in parallel — the global state is shared across the process.
- The `--allow-missing` / out-of-order migration story is documented but the recommendation to use `fix` in CI is a workaround for a fundamental team workflow problem, not a real solution. There's no built-in conflict detection for concurrent branch migrations.
- No native support for multi-tenant schemas or dynamic connection targets — if you need to run the same migrations against N tenant databases, you're writing the loop yourself with no helpers from the library.