Goose para Go: guía completa con ejemplos prácticos
¿Qué es Goose y para qué sirve?
La librería Goose (Go Object-Oriented SQL Environment) es una potente herramienta para gestionar migraciones de bases de datos en el ecosistema Go. A diferencia de las soluciones integradas, Goose ofrece un enfoque declarativo para el versionado del esquema de la BD, permitiendo a los desarrolladores describir los cambios en SQL o en código Go. Su objetivo principal es automatizar el proceso de aplicar y revertir cambios en la estructura de la base de datos, algo fundamental para el desarrollo en equipo y los pipelines de CI/CD.
¿Por qué usar Goose? Primero, resuelve el problema de sincronización del esquema de la BD entre desarrolladores: cada miembro del equipo puede aplicar las últimas migraciones con un solo comando. Segundo, Goose soporta versionado — cada migración tiene un número único, lo que permite saber exactamente qué cambios ya se aplicaron. Tercero, la librería funciona con varios sistemas de bases de datos (PostgreSQL, MySQL, SQLite, ClickHouse y otros) a través de una interfaz unificada, facilitando el cambio entre entornos.
La ventaja clave de Goose frente a alternativas (como golang-migrate/migrate) es su soporte para migraciones escritas en Go, no solo en SQL. Puedes crear migraciones complejas con lógica de negocio, usar transacciones y llamar a APIs externas. Además, Goose incluye soporte integrado para embed (incrustar migraciones en el binario), ideal para entornos de producción.
Instalación
La instalación de Goose se realiza a través del gestor de paquetes estándar de Go. Asegúrate de tener instalado Go versión 1.18 o superior.
go install github.com/pressly/goose/v3/cmd/goose@latest
Después de la instalación, verifica la versión:
goose --version
Para usar Goose como librería en tu proyecto, agrega la dependencia:
go get github.com/pressly/goose/v3
También necesitarás el driver para tu base de datos. Por ejemplo, para PostgreSQL:
go get github.com/lib/pq
Para MySQL:
go get github.com/go-sql-driver/mysql
Para SQLite:
go get github.com/mattn/go-sqlite3
Inicio rápido — ejemplo mínimo funcional
Vamos a crear un proyecto simple para demostrar las capacidades básicas de Goose.
1. Crea el directorio del proyecto e inicializa el módulo:
mkdir goose-demo && cd goose-demo
go mod init goose-demo
2. Crea el directorio para las migraciones:
mkdir migrations
3. Crea la primera migración en SQL. Archivo migrations/001_create_users.sql:
-- +goose Up
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- +goose Down
DROP TABLE users;
4. Crea el archivo main.go para ejecutar las migraciones desde código:
package main
import (
"database/sql"
"embed"
"log"
"github.com/pressly/goose/v3"
_ "github.com/lib/pq"
)
//go:embed migrations/*.sql
var migrations embed.FS
func main() {
// Conexión a la base de datos
db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=testdb sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Establecemos la fuente de migraciones desde embed.FS
goose.SetBaseFS(migrations)
// Ejecutamos las migraciones hasta la última versión
if err := goose.Up(db, "migrations"); err != nil {
log.Fa