Миграции в проекте рано или поздно превращаются в хаос. Кто-то забыл накатить скрипт, у кого-то локально другая версия схемы, а в проде вообще непонятно что.
goose — это инструмент для миграций на Go, который работает и как CLI, и как библиотека.Что умеет
goose поддерживает Postgres, MySQL, SQLite, ClickHouse, MSSQL, Spanner, YDB и ещё несколько баз. Миграции пишутся на SQL или на Go. Есть поддержка embed.FS, чтобы вшивать миграции прямо в бинарник. Можно применять миграции не по порядку, подставлять переменные окружения в SQL-файлы и запускать отдельные миграции без версионирования.
Если бинарник получается слишком большим, можно собрать без лишних драйверов:
go build -tags='no_postgres no_mysql no_sqlite3 no_ydb' -o goose ./cmd/goose
Как работать
Создаём первую миграцию:
goose create add_users_table sql
Goose сгенерирует файл вида
20250511120000_add_users_table.sql. Внутри два блока:-- +goose Up
CREATE TABLE users (
id int NOT NULL,
name text,
email text,
PRIMARY KEY(id)
);
-- +goose Down
DROP TABLE users;
Всё, что после
-- +goose Up, выполняется при накатывании миграции. Всё после -- +goose Down — при откате.Применяем все миграции:
goose postgres "user=postgres dbname=mydb sslmode=disable" up
Откатываем последнюю:
goose postgres "user=postgres dbname=mydb sslmode=disable" down
Смотрим статус:
goose postgres "user=postgres dbname=mydb sslmode=disable" status
Чтобы не передавать драйвер и строку подключения каждый раз, можно задать переменные окружения или положить их в
.env файл:GOOSE_DRIVER=postgres
GOOSE_DBSTRING=postgres://admin:admin@localhost:5432/mydb
GOOSE_MIGRATION_DIR=./migrations
Миграции на Go
Если SQL не хватает, миграции можно писать на Go:
package migrations
import (
"database/sql"
"github.com/pressly/goose/v3"
)
func init() {
goose.AddMigration(Up, Down)
}
func Up(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE users SET username='admin' WHERE username='root';")
return err
}
func Down(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE users SET username='root' WHERE username='admin';")
return err
}
Встраивание миграций в бинарник
С Go 1.16 можно вшить SQL-файлы миграций прямо в приложение через
embed.FS:package main
import (
"database/sql"
"embed"
"github.com/pressly/goose/v3"
)
//go:embed migrations/*.sql
var embedMigrations embed.FS
func main() {
var db *sql.DB
// настройка подключения к БД
goose.SetBaseFS(embedMigrations)
if err := goose.SetDialect("postgres"); err != nil {
panic(err)
}
if err := goose.Up(db, "migrations"); err != nil {
panic(err)
}
}
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
