Migrações de banco de dados em Go (Golang): guia completo
Ao desenvolver aplicações web em Go, mais cedo ou mais tarde surge a necessidade de alterar a estrutura do banco de dados: adicionar novas tabelas, modificar colunas existentes ou criar índices. A execução manual de scripts SQL em diferentes ambientes (desenvolvimento, staging, produção) leva a erros e dessincronização. A solução para este problema são as migrações de banco de dados.
Em Go, existem várias bibliotecas maduras para gerenciar migrações. Neste artigo, analisaremos detalhadamente as duas mais populares: golang-migrate/migrate e pressly/goose, além de fornecer exemplos de uso.
O que são migrações e por que são necessárias?
Uma migração é um conjunto versionado de comandos SQL (ou código Go) que é aplicado ao banco de dados sequencialmente. Cada migração possui um identificador único (geralmente um timestamp ou número) e pode ser aplicada (up) ou revertida (down).
Principais vantagens:
- Automação de alterações no esquema do BD
- Reprodutibilidade — resultado idêntico em qualquer ambiente
- Possibilidade de reverter alterações
- Armazenamento do histórico de alterações no código (amigável para VCS)
1. Biblioteca golang-migrate/migrate
Esta é a biblioteca mais popular para migrações em Go. Suporta PostgreSQL, MySQL, SQLite, MongoDB e outros SGBDs. As migrações podem ser escritas tanto em SQL puro quanto em Go.
Instalação
go get -u github.com/golang-migrate/migrate/v4Estrutura dos arquivos de migração
Os arquivos são colocados na pasta migrations/ e nomeados conforme o padrão:
{timestamp}_{title}.up.sql{timestamp}_{title}.down.sqlExemplo:
migrations/ 000001_create_users_table.up.sql 000001_create_users_table.down.sql 000002_add_email_to_users.up.sql 000002_add_email_to_users.down.sqlExemplo de migração SQL
Arquivo 000001_create_users_table.up.sql:
CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT NOW());Arquivo 000001_create_users_table.down.sql:
DROP TABLE IF EXISTS users;Aplicando migrações a partir do código 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://user:password@localhost:5432/dbname?sslmode=disable", ) if err != nil { panic(err) }
// Aplicar todas as migrações disponíveis (Up) if err := m.Up(); err != nil && err != migrate.ErrNoChange { panic(err) }
// Reverter a última migração (Down) // if err := m.Steps(-1); err != nil { // panic(err) // }}Ferramenta CLI migrate
Também está disponível um utilitário de linha de comando:
migrate create -ext sql -dir migrations -seq create_users_tablemigrate -path migrations -database "postgres://..." upmigrate -path migrations -database "postgres://..." down 12. Biblioteca pressly/goose
Goose é outra ferramenta popular, originalmente criada como análoga às migrações ActiveRecord do Ruby on Rails. Suporta migrações SQL e Go, além de um CLI integrado.
Instalação
go get -u github.com/pressly/goose/v3Estrutura dos arquivos
Os arquivos são nomeados como {timestamp}_{title}.sql (sem separação em up/down — tudo em um único arquivo através de comentários):
migrations/ 20240101120000_create_users_table.sql 20240102150000_add_email_to_users.sql