embed para Migrações SQL e Dados de Seed
O embed do Go 1.16+ permite que você envie arquivos de migração SQL e scripts de seed dentro do binário compilado.
Busque em todas as páginas da documentação
O embed do Go 1.16+ permite que você envie arquivos de migração SQL e scripts de seed dentro do binário compilado.
Os artefatos de implantação permanecem autocontidos: a mesma imagem de contêiner que executa a API pode aplicar versões de esquema sem montar um diretório de host.
//go:embed anexa arquivos ou diretórios a variáveis do tipo embed.FS.
As bibliotecas de migração aceitam adaptadores io/fs ou http.FileSystem sobre o FS incorporado.
Dados de seed para desenvolvimento e teste podem ser enviados em uma árvore incorporada separada das migrações de produção.
Cartão de receita de referência rápida - pronto para copiar e colar.
package migrations
import (
"embed"
"io/fs"
)
//go:embed sql/*.sql
var files embed.FS
func FS() fs.FS {
sub, _ := fs.Sub(files, "sql")
return sub
}import (
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
)
source, _ := iofs.New(migrations.FS(), ".")
m, _ := migrate.NewWithSourceInstance("iofs", source, dbURL)
_ = m.Up()Quando usar isso:
package main
import (
"database/sql"
"embed"
"fmt"
"io/fs"
"github.com/pressly/goose/v3"
_ "github.com/mattn/go-sqlite3"
)
//go:embed migrations/*.sql
var migrationFiles embed.FS
func main() {
db, _ := sql.Open("sqlite3", ":memory:")
defer db.Close()
goose.SetBaseFS(migrationFiles)
goose.SetDialect("sqlite3")
if err := goose.Up(db, "migrations"); err != nil {
panic(err)
}
var n int
_ = db.QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type='table'`).Scan(&n)
fmt.Println("tabelas:", n)
}migrations/00001_init.sql:
-- +goose Up
CREATE TABLE widgets (id INTEGER PRIMARY KEY, name TEXT);
-- +goose Down
DROP TABLE widgets;O que isso demonstra:
go:embed agrupa SQL ao lado do arquivo fonte Go.goose.SetBaseFS lê migrações da memória em vez do disco.iofs do golang-migrate.embed.FS é somente leitura e seguro para compartilhar entre goroutines.fs.Sub limita a raiz quando o SQL está em um subdiretório.| Caminho | Propósito |
|---|---|
migrations/*.sql | Esquema de subida/descida versionado |
seed/dev/*.sql | Fixtures locais (embed separado opcional) |
testdata/schema.sql | Inicialização de teste de integração |
internal/migrations | Pacote que exporta FS() para main |
d, err := iofs.New(migrations.FS(), ".")
m, err := migrate.NewWithInstance("iofs", d, "postgres", dbURL)"iofs" combina com o nome do driver do banco de dados em NewWithInstance.//go:embed seed/* separado importado apenas de main_dev.go.INSERT ... ON CONFLICT DO NOTHING ou migração Go do goose com loops.go:embed.fs.FS.go run da raiz do módulo.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Volume ConfigMap (K8s) | Ops quer hot-patch SQL sem recompilação | Você precisa de artefatos de release imutáveis |
| Checkout Git no contêiner | Dockerfile simples COPY migrations | Imagens Distroless sem shell |
| Serviço de migração remota | Registro de esquema central | Pequenas equipes querem simplicidade incorporada |
go:generate para empacotar SQL | Pipeline de codegen personalizado | O embed padrão é suficiente |
| Flyway no sidecar JVM | Padrão corporativo | Unidade de implantação Go pura |
Sim - os testes importam o mesmo pacote e chamam goose.Up contra bancos de dados efêmeros.
Mantenha os arquivos de migração no pacote sob teste.
Use variáveis separadas e diretivas //go:embed por diretório.
O prefixo all: incorpora arquivos ocultos, se necessário.
Tags de compilação em arquivos (//go:build dev) ou comandos/pacotes separados.
O main de produção importa apenas o pacote de migração de produção.
//go:embed migrations incorpora a árvore; use fs.Sub para definir a raiz do diretório do goose.
Verifique os alvos da placa na compilação; builds WASM e embarcados podem ter limites de tamanho.
Teste o tamanho da migração em alvos restritos.
go test que executa Up e afirma que as tabelas existem.
Falhe na compilação se o padrão estiver vazio.
Arquivos de migração Go compilam no binário naturalmente; SQL usa embed.FS.
Escolha um estilo por repositório para clareza na revisão.
O CLI no laptop ainda pode usar -path ./migrations enquanto o binário de produção usa iofs - mantenha os arquivos idênticos no git.
Os mesmos arquivos down do fluxo de disco; o embed apenas muda o transporte.
A disciplina de rollback permanece inalterada.
O limite prático é o tamanho do binário e a memória, não a sintaxe Go.
Divida grandes migrações de dados em migrações Go em lotes.
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 (última - verifique na compilação), gin (última - verifique na compilação), echo (última - verifique na compilação), google.golang.org/grpc (última - verifique na compilação), sigs.k8s.io/controller-runtime (última - verifique na compilação), kubebuilder (última - verifique na compilação), tinygo (última - verifique os alvos da placa na compilação), wazero (última - verifique na compilação) e golangci-lint (última - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026