Migrações com golang-migrate & goose
Alterações de esquema pertencem a arquivos de migração versionados, não a ALTER ad hoc na inicialização do aplicativo.
Busque em todas as páginas da documentação
Alterações de esquema pertencem a arquivos de migração versionados, não a ALTER ad hoc na inicialização do aplicativo.
golang-migrate e goose são ferramentas populares compatíveis com Go que aplicam migrações SQL (ou Go) ordenadas e suportam rollbacks em pipelines de CI e implantação.
Migrações são arquivos com timestamp ou sequenciados com seções up e down.
Aplique migrações antes que o novo código sirva tráfego, ou use padrões expand-contract para implantações sem tempo de inatividade.
Execute trabalhos de migração em CI contra bancos de dados efêmeros para capturar erros SQL precocemente.
Nunca execute migrações dentro de manipuladores HTTP por solicitação.
Cartão de receita de referência rápida - pronto para copiar e colar.
# CLI do golang-migrate
migrate -path ./migrations -database "${DATABASE_URL}" up
migrate -path ./migrations -database "${DATABASE_URL}" down 1
# CLI do goose
goose -dir ./migrations postgres "$DATABASE_URL" up
goose -dir ./migrations postgres "$DATABASE_URL" down// incorporar migrações (veja artigo irmão)
//go:embed migrations/*.sql
var migrationFS embed.FSQuando usar isso:
down restauram a forma anterior no staging.package main
import (
"database/sql"
"fmt"
"log"
"github.com/pressly/goose/v3"
_ "github.com/jackc/pgx/v5/stdlib"
)
func main() {
db, err := sql.Open("pgx", "postgres://localhost:5432/app?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
goose.SetDialect("postgres")
if err := goose.Up(db, "migrations"); err != nil {
log.Fatal(err)
}
fmt.Println("migrações aplicadas")
}Exemplo migrations/00001_create_users.sql:
-- +goose Up
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email TEXT NOT NULL UNIQUE
);
-- +goose Down
DROP TABLE users;O que isso demonstra:
goose.Up aplica arquivos pendentes em ordem lexical.SetDialect seleciona peculiaridades SQL para Postgres, MySQL ou SQLite.schema_migrations ou tabela de versão do goose).up executa arquivos pendentes; down reverte as últimas N etapas.000001_init.up.sql e 000001_init.down.sql.| Etapa | Proprietário | Ação |
|---|---|---|
| PR | Desenvolvedor | Adicionar migração + código do aplicativo no mesmo PR |
| CI | Pipeline | Iniciar banco de dados efêmero, up, executar testes, down opcional |
| Staging | Lançamento | up antes de rolar os pods |
| Produção | Lançamento | up com snapshot de backup; monitorar locks |
Alterações que quebram compatibilidade (NOT NULL sem padrão, renomear no local) exigem lançamentos multifásicos.
| Ferramenta | Força | Contrapartida |
|---|---|---|
| golang-migrate | Amplamente utilizado, CLI + biblioteca | Migrações Go precisam de layout de pacote separado |
| goose | Migrações Go no mesmo módulo | A equipe deve concordar com o formato de anotação |
| GORM AutoMigrate | Protótipos rápidos | História de revisão fraca para esquema de produção |
down ausente - Simulações de rollback falham. Correção: exigir down na revisão para alterações reversíveis; documentar operações irreversíveis.ALTER. Correção: executar migrações pesadas como trabalho de manutenção separado com monitoramento de locks.AutoMigrate na inicialização do aplicativo em produção - Corrida entre réplicas; diferenças não rastreadas. Correção: trabalho de migração explícito com tabela de versão.up antes dos testes.down destrutivo em produção - Perda de dados no rollback. Correção: tratar down apenas para staging; rollbacks de produção restauram backups.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Flyway/Liquibase (JVM) | Padrão organizacional poliglota | Loja puramente Go quer migrações incorporadas |
| GORM AutoMigrate | Esquema de hackathon | Esquema de produção auditado |
| Runbooks manuais do DBA | Mainframes de toque raro | Equipes de produto em rápida evolução |
| sqlc sem migrações | Apenas consultas | Você ainda precisa de versionamento de esquema em algum lugar |
| Atlas / skeema | Estado desejado declarativo | Equipe prefere arquivos up/down imperativos |
Incorporação de biblioteca mais Up na inicialização é aceitável para pequenos serviços.
Equipes maiores preferem um Job do Kubernetes ou hook de lançamento para que os pods do aplicativo iniciem apenas após o esquema estar pronto.
Use sequência preenchida com zeros ou timestamps UTC; nunca reutilize números.
Uma mudança lógica por arquivo facilita a revisão.
Escolha uma ferramenta por repositório para evitar tabelas de versão concorrentes.
Migrar ferramentas é um projeto único com uma janela de congelamento.
Scripts de seed separados ou migrações Go do goose para fixtures de desenvolvimento.
Seeds de produção pertencem a trabalhos idempotentes, não a SQL aleatório em up.
Frequentemente, correção para frente com uma nova migração em vez de down.
down é mais valioso em CI e em laptops de desenvolvedores.
CLI e jobs podem usar context.Background() com cancelamento controlado por operações.
Não vincule alterações de esquema ao contexto de solicitação HTTP.
CI: up, testes de integração, down, up novamente para detectar scripts não idempotentes.
Contagem de linhas de snapshot para migrações de dados.
Papel capaz de DDL usado apenas no trabalho de implantação; o tempo de execução do aplicativo usa privilégios menores.
Usuários separados reduzem o raio de explosão.
Veja embed para Migrações SQL e Dados de Seed para agrupar arquivos dentro do binário.
Útil para preenchimentos complexos com logging e batching.
Mantenha DDL simples em SQL para revisabilidade pelo DBA.
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão GC Green Tea, go fix modernizers - verifique o patch na compilação), chi (mais recente - verifique na compilação), gin (mais recente - verifique na compilação), echo (mais recente - verifique na compilação), google.golang.org/grpc (mais recente - verifique na compilação), sigs.k8s.io/controller-runtime (mais recente - verifique na compilação), kubebuilder (mais recente - verifique na compilação), tinygo (mais recente - verifique os alvos de placa na compilação), wazero (mais recente - verifique na compilação) e golangci-lint (mais recente - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026