golang-migrate
Тема дорожной карты · Golang
Миграции баз данных в Go — версионированные SQL-скрипты, постепенно изменяющие реляционную схему в воспроизводимой, допускающей откат форме; golang-migrate и goose — стандартные инструменты в Golang-экосистеме. golang-migrate поддерживает несколько драйверов баз данных — PostgreSQL через pgx, MySQL, SQLite — и может управляться из CLI командой migrate up или встраиваться непосредственно в Go-код через конструктор migrate.New и метод m.Up(). Миграции баз данных в Go, как правило, хранятся в директории migrations/ с именами файлов, включающими временну́ю метку, — например 000001_create_users.up.sql и 000001_create_users.down.sql, — что упрощает аудит истории схемы в Git. Запуск миграций при старте приложения через m.Up() до начала приёма трафика — распространённый паттерн для Golang-сервисов, развёрнутых в Kubernetes: он гарантирует синхронизацию схемы с версией бинарника. Правильное управление миграциями баз данных в Go предотвращает расхождение схем между средами и является обязательной практикой для любого продакшен Golang-бэкенда, использующего GORM, sqlx или pgx.
Как это работает
golang-migrate использует database/sql (интерфейс) + драйвер (pgx для Postgres — также экспонирует свой native-API, go-sql-driver/mysql для MySQL, mattn/go-sqlite3 для SQLite). Connection pool встроен в database/sql. ORM: GORM (популярный, full-featured, opinionated), Ent (Facebook, code-gen based), Bun (sqlx-like), sqlx (расширяет stdlib). Для миграций: golang-migrate, goose, atlas.
Когда применять
По умолчанию сырой database/sql + sqlx для явных запросов; ORM (GORM, Ent) — только если команда реально хочет. pgx напрямую (pgxpool) — для Postgres: лучшая производительность + Postgres-специфика (массивы, JSONB, COPY). Всегда параметризованные запросы ($1/? placeholders). Миграции — через тул, не через Go-код.
Типичные ошибки
Ловушки golang-migrate: SQL-инъекция через fmt.Sprintf в запрос (всегда параметризуйте); утечка *sql.Rows (всегда defer rows.Close()); магия GORM прячет N+1 запросы; не выставлен db.SetMaxOpenConns — исчерпание соединений Postgres; context.Background() вместо контекста запроса (запросы нельзя отменить).