Миграции баз данных в Go (Golang): как управлять схемой данных
При разработке приложений на Go рано или поздно возникает необходимость изменять структуру базы данных: добавлять новые таблицы, изменять существующие столбцы, создавать индексы. Ручное выполнение SQL-скриптов на разных окружениях (локальная среда разработки, стейджинг, продакшн) приводит к ошибкам и рассинхронизации. Решение — миграции баз данных (database migrations).
В экосистеме Go существует несколько зрелых библиотек для управления миграциями. В этой статье мы подробно разберём три самых популярных инструмента: golang-migrate/migrate, pressly/goose и rubenv/sql-migrate. Вы узнаете, как установить, настроить и использовать каждую из них, а также познакомитесь с лучшими практиками.
Что такое миграции и зачем они нужны?
Миграция — это файл (или набор файлов), который содержит SQL-команды для изменения схемы базы данных. Каждая миграция имеет уникальный идентификатор (обычно временная метка или номер) и два направления: up (применение изменений) и down (откат изменений).
Основные преимущества использования миграций:
- Версионирование схемы — история изменений хранится в репозитории вместе с кодом.
- Воспроизводимость — одинаковые изменения на всех окружениях.
- Откат изменений — возможность быстро вернуться к предыдущей версии схемы.
- Командная работа — разработчики не перезаписывают изменения друг друга.
1. golang-migrate/migrate
Самая популярная библиотека для миграций в Go. Поддерживает PostgreSQL, MySQL, SQLite, MongoDB и многие другие базы данных.
Установка
go get -u github.com/golang-migrate/migrate/v4
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
Структура миграций
Создайте папку migrations и добавьте файлы с префиксом в формате {timestamp}_{title}.{direction}.sql:
migrations/
000001_create_users_table.up.sql
000001_create_users_table.down.sql
000002_add_email_column.up.sql
000002_add_email_column.down.sql
Пример миграции (up)
-- 000001_create_users_table.up.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
Пример миграции (down)
-- 000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;
Применение миграций из Go-кода
package main
import (
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
)
func main() {
m, err := migrate.New(
"file://migrations",
"postgres://localhost:5432/mydb?sslmode=disable")
if err != nil {
panic(err)
}
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
panic(err)
}
}
2. pressly/goose
Goose — лёгкий и быстрый инструмент, который также поддерживает написание миграций на Go (не только на SQL). Идеально подходит для проектов, где требуется логика на стороне кода.
Установка
go get github.com/pressly/goose/v3/cmd/goose
Создание миграции
goose create create_users_table sql
Будет создан файл вида 20250101120000_create_users_table.sql. Содержимое:
-- +goose Up
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
-- +goose Down
DROP TABLE IF EXISTS users;
Go-миграции (продвинутый вариант)
Goose позволяет писать миграции на Go с использованием database/sql:
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("CREATE TABLE items (id SERIAL PRIMARY KEY, name TEXT)")
return err
}
func Down(tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE IF EXISTS items")
return err
}
Также в библиотеке
WebSocket библиотеки Java: Полное руководство по реализации реального времени
Psycopg2 – драйвер PostgreSQL
Парсинг HTML в Swift (iOS/macOS): библиотеки SwiftSoup и Fuzi
Работа с изображениями в PHP: полное руководство по GD и Imagick
Машинное обучение на C# (.NET): обзор библиотек ML.NET, Accord.NET, TensorFlow.NET
Рекомендаций
Также в библиотеке
WebSocket библиотеки Java: Полное руководство по реализации реального времени
Парсинг HTML в Swift (iOS/macOS): библиотеки SwiftSoup и Fuzi
Работа с изображениями в PHP: полное руководство по GD и Imagick
Машинное обучение на C# (.NET): обзор библиотек ML.NET, Accord.NET, TensorFlow.NET