Skip to content

Advanced

Naming patterns, multi-environment setup, metadata tracking, and .queenignore.

Naming Patterns

Control how migration versions are formatted with NamingConfig.

Available Patterns

Pattern Example Description
sequential 1, 2, 3 Plain integers, no leading zeros
sequential-padded 001, 002, 003 Fixed-width with zero padding
semver 1.0.0, 1.1.0 Semantic versioning

Configuration

q := queen.NewWithConfig(driver, &queen.Config{
    Naming: &queen.NamingConfig{
        Pattern: queen.NamingPatternSequentialPadded,
        Padding: 3,     // 001, 002, ..., 999
        Enforce: true,   // Reject non-matching versions
    },
})

When Enforce is true, Add returns an error if the version does not match the pattern. When false, a warning is logged but the migration is accepted.

Auto-Generation

NamingConfig can generate the next version from existing ones:

nc := &queen.NamingConfig{
    Pattern: queen.NamingPatternSequentialPadded,
    Padding: 3,
}
next, err := nc.FindNextVersion([]string{"001", "002", "003"})
// next = "004"

Semver does not support auto-generation. Specify versions manually.

CLI

queen create add_posts   # Auto-generates next version based on naming config

Environments

Queen supports multi-environment configuration through QUEEN_ENV and the CLI config file.

Environment Variable

Set QUEEN_ENV to tag migrations with the current environment:

QUEEN_ENV=production queen up

The environment name is stored in the migration record metadata.

CLI Config File

Create .queen.yaml for per-environment database settings:

development:
  driver: postgres
  dsn: "postgres://localhost/myapp_dev?sslmode=disable"
staging:
  driver: postgres
  dsn: "postgres://staging-host/myapp?sslmode=require"
production:
  driver: postgres
  dsn: "postgres://prod-host/myapp?sslmode=verify-full"
queen up --use-config --env production

Multiple Databases

Create separate Queen instances for each database:

qPrimary := queen.New(postgres.New(dbPrimary))
qAnalytics := queen.New(clickhouse.New(dbAnalytics))

Isolation Levels

Set transaction isolation levels globally or per-migration.

Global Default

q := queen.NewWithConfig(driver, &queen.Config{
    IsolationLevel: sql.LevelSerializable,
})

Per-Migration Override

q.MustAdd(queen.M{
    Version:        "005",
    Name:           "financial_update",
    UpSQL:          `UPDATE accounts SET balance = balance * 1.01`,
    DownSQL:        `UPDATE accounts SET balance = balance / 1.01`,
    IsolationLevel: sql.LevelSerializable,
})

Priority: Migration-level > Config-level > sql.LevelDefault.


.queenignore

The .queenignore file tells Queen to skip specific migration gaps during gap detection.

File Format

Plain text. One version per line. Comments after #:

# .queenignore - Ignored migration gaps
# Format: version # reason

003 # Not needed in this environment
007 # Deprecated, replaced by 008

Library API

qi, err := queen.LoadQueenIgnore()            // Loads .queenignore from current directory
qi, err := queen.LoadQueenIgnoreFrom("path")  // Custom path

qi.IsIgnored("003")                           // true
qi.GetReason("003")                           // "Not needed in this environment"

qi.AddIgnore("009", "Skipped on staging", "admin")
qi.RemoveIgnore("003")
qi.Save()

ignored := qi.ListIgnored()
for _, g := range ignored {
    fmt.Printf("%s: %s\n", g.Version, g.Reason)
}

CLI

queen gap ignore 003 --reason "Not needed in this environment"
queen gap list-ignored
queen gap unignore 003

Custom Migration Table

Change the table name where Queen stores migration records:

q := queen.NewWithConfig(driver, &queen.Config{
    TableName: "my_migrations",
})

Or per-driver:

driver := postgres.NewWithTableName(db, "my_migrations")

CLI

queen up --table my_migrations

Logging

Queen uses a structured logger compatible with *slog.Logger:

import "log/slog"

q := queen.New(driver, queen.WithLogger(slog.Default()))

The Logger interface:

type Logger interface {
    InfoContext(ctx context.Context, msg string, args ...any)
    WarnContext(ctx context.Context, msg string, args ...any)
    ErrorContext(ctx context.Context, msg string, args ...any)
}

Queen logs migration start/complete events, lock acquisition, checksum warnings, and errors. Use a custom logger to integrate with your application's logging infrastructure.