Skip to content

First Migration

This guide demonstrates creating and applying your first Queen migration.

Prerequisites

  • Go 1.24+
  • Database running (PostgreSQL in this example)
  • Queen installed: go get github.com/honeynil/queen

Step 1: Create Project

mkdir myapp && cd myapp
go mod init myapp
go get github.com/honeynil/queen
go get github.com/jackc/pgx/v5/stdlib

Step 2: Database Connection

Create main.go:

package main

import (
    "context"
    "database/sql"
    "log"

    "github.com/honeynil/queen"
    "github.com/honeynil/queen/drivers/postgres"
    _ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
    db, err := sql.Open("pgx", "postgres://localhost/myapp?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    if err := db.Ping(); err != nil {
        log.Fatal("Database connection failed:", err)
    }

    log.Println("Connected to database")
}

Test connection:

go run main.go

Step 3: Initialize Queen

func main() {
    db, err := sql.Open("pgx", "postgres://localhost/myapp?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    driver := postgres.New(db)
    q := queen.New(driver)
    defer q.Close()

    log.Println("Queen initialized")
}

Step 4: Register Migration

func main() {
    // ... database connection and Queen initialization

    q.MustAdd(queen.M{
        Version: "001",
        Name:    "create_users_table",
        UpSQL: `
            CREATE TABLE users (
                id SERIAL PRIMARY KEY,
                email VARCHAR(255) NOT NULL UNIQUE,
                name VARCHAR(255),
                created_at TIMESTAMP DEFAULT NOW()
            )
        `,
        DownSQL: `DROP TABLE users`,
    })

    log.Println("Migration registered")
}

Step 5: Apply Migration

func main() {
    // ... previous code

    ctx := context.Background()
    if err := q.Up(ctx); err != nil {
        log.Fatal("Migration failed:", err)
    }

    log.Println("Migration applied")
}

Complete Example

package main

import (
    "context"
    "database/sql"
    "log"

    "github.com/honeynil/queen"
    "github.com/honeynil/queen/drivers/postgres"
    _ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
    db, err := sql.Open("pgx", "postgres://localhost/myapp?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    driver := postgres.New(db)
    q := queen.New(driver)
    defer q.Close()

    q.MustAdd(queen.M{
        Version: "001",
        Name:    "create_users_table",
        UpSQL: `
            CREATE TABLE users (
                id SERIAL PRIMARY KEY,
                email VARCHAR(255) NOT NULL UNIQUE,
                name VARCHAR(255),
                created_at TIMESTAMP DEFAULT NOW()
            )
        `,
        DownSQL: `DROP TABLE users`,
    })

    ctx := context.Background()
    if err := q.Up(ctx); err != nil {
        log.Fatal("Migration failed:", err)
    }

    log.Println("All migrations applied")

    statuses, err := q.Status(ctx)
    if err != nil {
        log.Fatal(err)
    }

    for _, s := range statuses {
        log.Printf("Migration %s (%s): %s", s.Version, s.Name, s.Status)
    }
}

Next Steps