Skip to content

Configuration

Queen can be configured through code, environment variables, or YAML files.

Basic Configuration

Default Configuration

q := queen.New(driver)

Uses defaults: - Table name: queen_migrations - Lock timeout: 30 minutes - Lock enabled: true

Custom Configuration

config := &queen.Config{
    TableName:   "custom_migrations",
    LockTimeout: 15 * time.Minute,
    SkipLock:    false,
}

q := queen.NewWithConfig(driver, config)

Configuration Options

Table Name

Customize the migrations table name:

config := &queen.Config{
    TableName: "my_migrations",
}

Default: queen_migrations

Lock Timeout

Set advisory lock timeout:

config := &queen.Config{
    LockTimeout: 45 * time.Minute,
}

Default: 30 * time.Minute

Prevents concurrent migrations from different instances.

Skip Lock

Disable advisory locks:

config := &queen.Config{
    SkipLock: true,
}

Default: false

Warning

Only disable locks if you control migration execution through other means.

Naming Patterns

Enforce version naming patterns:

config := &queen.Config{
    Naming: &queen.NamingConfig{
        Pattern: queen.NamingPatternSequentialPadded,
        Padding: 3,
        Enforce: true,
    },
}

Available patterns:

Pattern Example versions
NamingPatternSequential 1, 2, 3
NamingPatternSequentialPadded 001, 002, 003
NamingPatternSemver 1.0.0, 1.1.0

When Enforce is true, Add returns an error if the version does not match the pattern.

Isolation Level

Set transaction isolation level:

config := &queen.Config{
    IsolationLevel: sql.LevelSerializable,
}

Options: - sql.LevelDefault - sql.LevelReadUncommitted - sql.LevelReadCommitted - sql.LevelRepeatableRead - sql.LevelSerializable

Can also be set per migration:

q.MustAdd(queen.M{
    Version: "001",
    Name:    "create_users",
    IsolationLevel: sql.LevelSerializable,
    UpSQL: `CREATE TABLE users (...)`,
})

Logger Configuration

Default Logger

Queen uses a default logger internally:

q := queen.New(driver)

Custom Logger

Provide your own *slog.Logger:

import "log/slog"

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
q := queen.New(driver, queen.WithLogger(logger))

Disable Logging

import "log/slog"

logger := slog.New(slog.NewTextHandler(io.Discard, nil))
q := queen.New(driver, queen.WithLogger(logger))

CLI Configuration

Environment Variables

export QUEEN_DRIVER=postgres
export QUEEN_DSN="postgres://localhost/mydb"
export QUEEN_TABLE=queen_migrations

Run:

queen up

Config File (.queen.yaml)

Create .queen.yaml:

naming:
  pattern: sequential_padded
  padding: 3
  enforce: true

development:
  driver: postgres
  dsn: "postgres://localhost/mydb_dev?sslmode=disable"

Use:

queen up --use-config

Multiple Environments

development:
  driver: postgres
  dsn: "postgres://localhost/mydb_dev?sslmode=disable"

staging:
  driver: postgres
  dsn: "postgres://staging.example.com/mydb?sslmode=require"

production:
  driver: postgres
  dsn: "postgres://prod.example.com/mydb?sslmode=verify-full"
  require_confirmation: true
  require_explicit_unlock: true

Run:

# Development (default)
queen up --use-config

# Staging
queen up --use-config --env staging

# Production (requires unlock flag)
queen up --use-config --env production --unlock-production

Command-line Flags

Override config with flags:

queen up \
  --driver postgres \
  --dsn "postgres://localhost/mydb" \
  --table migrations \
  --timeout 45m

Configuration Priority

Priority (highest to lowest):

  1. Command-line flags
  2. Environment variables
  3. Config file (.queen.yaml)
  4. Defaults

Complete Example

package main

import (
    "database/sql"
    "log/slog"
    "os"
    "time"

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

func main() {
    db, _ := sql.Open("pgx", os.Getenv("DATABASE_URL"))
    driver := postgres.New(db)

    logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
        Level: slog.LevelInfo,
    }))

    config := &queen.Config{
        TableName:      "migrations",
        LockTimeout:    15 * time.Minute,
        SkipLock:       false,
        IsolationLevel: sql.LevelReadCommitted,
        Naming: &queen.NamingConfig{
            Pattern: queen.NamingPatternSequentialPadded,
            Padding: 3,
            Enforce: true,
        },
    }

    q := queen.NewWithConfig(driver, config)
    defer q.Close()

    // Note: WithLogger is a functional option for queen.New(), not NewWithConfig().
    // To use both custom config and a logger, use queen.New() with WithLogger:
    //   q := queen.New(driver, queen.WithLogger(logger))
    // NewWithConfig does not accept functional options.
    _ = logger

    // Register migrations...
}

Next Steps