goose for Go: complete guide with examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course
\n

goose for Go: complete guide with examples

\n\n
\n

What it is and why you need it

\n

The goose library (Go Object-Oriented SQL Environment) is a powerful tool for managing database migrations in the Go ecosystem. Unlike built-in solutions, goose provides a declarative approach to database schema versioning, allowing developers to describe changes in SQL or Go code. The main task of goose is to automate the process of applying and rolling back database structure changes, which is critical for team development and CI/CD pipelines.

\n

Why do you need goose? First, it solves the problem of database schema synchronization between developers: each team member can apply the latest migrations with a single command. Second, goose supports versioning — each migration has a unique number, allowing you to accurately determine which changes have already been applied. Third, the library can work with various DBMS (PostgreSQL, MySQL, SQLite, ClickHouse and others) through a unified interface, simplifying switching between environments.

\n

The key advantage of goose over alternatives (e.g., golang-migrate/migrate) is support for migrations in Go, not just SQL. You can write complex migrations with business logic, use transactions, and call external APIs. Additionally, goose provides built-in support for embed (embedding migrations into the binary), which is ideal for production environments.

\n
\n\n
\n

Installation

\n

Installation of goose is done through the standard Go package manager. First, make sure you have Go version 1.18 or higher installed.

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

After installation, check the version:

\n
goose --version
\n

To use goose as a library in your project, add the dependency:

\n
go get github.com/pressly/goose/v3
\n

You will also need a driver for your DBMS. For example, for PostgreSQL:

\n
go get github.com/lib/pq
\n

For MySQL:

\n
go get github.com/go-sql-driver/mysql
\n

For SQLite:

\n
go get github.com/mattn/go-sqlite3
\n
\n\n
\n

Quick start — minimal working example

\n

Let's create a simple project to demonstrate the basic capabilities of goose.

\n

1. Create a project directory and initialize the module:

\n
mkdir goose-demo && cd goose-demo\ngo mod init goose-demo
\n

2. Create a directory for migrations:

\n
mkdir migrations
\n

3. Create the first migration in SQL. File migrations/001_create_users.sql:

\n
-- +goose Up\nCREATE TABLE users (\n    id SERIAL PRIMARY KEY,\n    name VARCHAR(255) NOT NULL,\n    email VARCHAR(255) UNIQUE NOT NULL,\n    created_at TIMESTAMP DEFAULT NOW()\n);\n\n-- +goose Down\nDROP TABLE users;
\n

4. Create a main.go file for programmatically running migrations:

\n
package main\n\nimport (\n    "database/sql"\n    "embed"\n    "log"\n\n    "github.com/pressly/goose/v3"\n    _ "github.com/lib/pq"\n)\n\n//go:embed migrations/*.sql\nvar migrations embed.FS\n\nfunc main() {\n    // Connecting to the database\n    db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=testdb sslmode=disable")\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer db.Close()\n\n    // Setting the migration source from embed.FS\n    goose.SetBaseFS(migrations)\n\n    // Running migrations to the latest version                    

Recommendations