Bem-vindo ao Blog da DMarkInfo

Conteúdos e novidades sobre Tecnologia da Informação.

Dominando Migrations no Go: como versionar e evoluir seu banco de dados com segurança

Postado por Eduardo Marques em 29/10/2025
Dominando Migrations no Go: como versionar e evoluir seu banco de dados com segurança

Quando você trabalha em equipe, um dos maiores desafios é manter o banco de dados sincronizado entre os ambientes.
Alterar uma tabela, adicionar uma coluna ou criar uma nova estrutura pode parecer simples — até que alguém esquece de rodar aquele
script SQL manual, e a aplicação quebra.

É aqui que entram as migrations: uma forma elegante e segura de versionar o banco de dados junto com o código.
Neste artigo, você vai aprender o que são migrations, como usá-las em Go com o Goose, e boas práticas para manter seu banco sempre sob controle.

O que são migrations?

De forma simples, migrations são scripts versionados que descrevem mudanças no banco de dados.
Cada migration representa um passo na evolução do schema — e você pode “subir” ou “descer” versões conforme necessário.

Em frameworks como Django (Python) ou Rails (Ruby), migrations são parte do core.
No Go, não existe um padrão oficial, mas há ótimas bibliotecas que cumprem esse papel:

Neste artigo, vamos usar o Goose, por ser leve e fácil de integrar em qualquer projeto Go.

 

Configurando migrations com Goose

Vamos colocar a mão na massa.
Crie uma pasta para seu projeto e instale o Goose:

go install github.com/pressly/goose/v3/cmd/goose@latest

Estrutura básica do projeto:

├── db/
│   └── migrations/
├── main.go
├── go.mod

Criando a primeira migration

O comando abaixo cria um novo arquivo de migration:

goose create create_users_table sql

Isso vai gerar algo como:

db/migrations/20251029090000_create_users_table.sql

Abra o arquivo e adicione o conteúdo:

-- +goose Up
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
);

-- +goose Down
DROP TABLE users;

As seções Up e Down definem, respectivamente, o que fazer ao subir e reverter a migration.

Aplicando migrations

Agora é só executar:

goose postgres "user=postgres dbname=test sslmode=disable" up

Isso aplicará todas as migrations pendentes.
Se quiser desfazer a última:

goose postgres "user=postgres dbname=test sslmode=disable" down

E para verificar o status:

goose postgres "user=postgres dbname=test sslmode=disable" status

 

Rodando migrations automaticamente no código Go

Você também pode aplicar migrations automaticamente ao iniciar sua aplicação:

package main

import (
    "database/sql"
    "log"

    _ "github.com/lib/pq"
    "github.com/pressly/goose/v3"
)

func main() {
    db, err := sql.Open("postgres", "user=postgres dbname=test
sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    if err := goose.Up(db, "db/migrations"); err != nil {
        log.Fatal(err)
    }

    log.Println("Migrations aplicadas com sucesso!")
}

Agora, sempre que a aplicação iniciar, ela garantirá que o banco está atualizado.

 

Boas práticas com migrations

  1. Nomeie migrations de forma clara
    Use nomes descritivos como add_index_to_users_email.sql.

  2. Sempre inclua rollback (Down)
    É vital poder desfazer mudanças em caso de erro.

  3. Evite alterar migrations antigas
    Cada migration deve refletir o estado histórico do banco.

  4. Automatize no CI/CD
    Adicione um passo no pipeline para rodar migrations automaticamente.

  5. Teste migrations antes de subir em produção
    Use um banco de staging para validar.

  6. Mantenha as migrations versionadas junto com o código
    Isso garante reprodutibilidade entre ambientes (dev, staging, prod).

Comparando ferramentas de migrations em Go

Ferramenta Estilo Linguagem das migrations Suporte a rollback Nível de automação Ideal para
Goose Simples, manual SQL ou Go ✅ Sim Médio Projetos diretos
Migrate CLI robusta SQL ✅ Sim Médio/Alto Ambientes complexos
GORM AutoMigrate Automática Structs Go ❌ Não (sem rollback) Alto Protótipos rápidos

 

Dica: prefira Goose ou Migrate para produção, pois permitem controle total sobre cada alteração.

Gerenciar a evolução do banco de dados é tão importante quanto versionar o código.
Com o Goose, você ganha controle, rastreabilidade e segurança — garantindo que todos os ambientes estejam sempre alinhados.

Próximo passo?
No próximo artigo, vou mostrar como automatizar migrations Go com Docker e CI/CD, integrando esse processo ao pipeline de deploy.

Compartilhe este post:
Voltar para a Home