Ответ
Да, я регулярно работал с миграциями баз данных. В Go-проектах наиболее популярны два подхода: использование .sql
файлов и написание миграций на самом Go.
Я использовал следующие инструменты:
-
golang-migrate/migrate
: Это, пожалуй, самая популярная и универсальная библиотека. Она поддерживает огромное количество баз данных и источников миграций (файлы, go-bindata, S3 и т.д.).- Подход: Используются
.sql
файлы с определенным форматом именования, например:000001_create_users_table.up.sql
и000001_create_users_table.down.sql
. - Пример
...up.sql
файла:CREATE TABLE users ( id UUID PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP );
- Подход: Используются
-
pressly/goose
: Еще один популярный инструмент, который также делает упор на.sql
файлы, но с другим синтаксисом внутри файла.- Подход: Используются комментарии
-- +goose Up
и-- +goose Down
в одном SQL-файле. -
Пример файла миграции:
-- +goose Up CREATE TABLE products ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, price NUMERIC(10, 2) NOT NULL ); -- +goose Down DROP TABLE products;
- Подход: Используются комментарии
-
Программные миграции: Иногда, если логика миграции сложна (например, требует переноса и трансформации данных), миграции пишутся на Go. Это можно сделать с помощью того же
golang-migrate/migrate
или других библиотек.-
Пример запуска миграций из кода:
import "github.com/golang-migrate/migrate/v4" // ... импорты драйверов БД и источников func RunMigrations(databaseURL, migrationsPath string) error { m, err := migrate.New( "file://" + migrationsPath, // источник миграций databaseURL, // URL подключения к БД ) if err != nil { return err } // Применяем все доступные миграции "вверх" if err := m.Up(); err != nil && err != migrate.ErrNoChange { return err } return nil }
-
Выбор инструмента зависит от проекта. Для большинства CRUD-сервисов я предпочитаю golang-migrate/migrate
с SQL-файлами за его простоту, наглядность и независимость от кода приложения. Программные миграции использую в редких случаях, когда требуется сложная логика преобразования данных.