Package rivermigrate provides a Go API for running migrations as alternative to migrating via the bundled CLI.
Example_migrate demonstrates the use of River's Go migration API by migrating up and down.
package main
import (
"context"
"fmt"
"strings"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/riverqueue/river/riverdbtest"
"github.com/riverqueue/river/riverdriver/riverpgxv5"
"github.com/riverqueue/river/rivermigrate"
"github.com/riverqueue/river/rivershared/riversharedtest"
"github.com/riverqueue/river/rivershared/util/testutil"
)
func main() {
ctx := context.Background()
dbPool, err := pgxpool.New(ctx, riversharedtest.TestDatabaseURL())
if err != nil {
panic(err)
}
defer dbPool.Close()
driver := riverpgxv5.New(dbPool)
migrator, err := rivermigrate.New(driver, &rivermigrate.Config{
// Test schema with no migrations for purposes of this test.
Schema: riverdbtest.TestSchema(ctx, testutil.PanicTB(), driver, &riverdbtest.TestSchemaOpts{Lines: []string{}}),
})
if err != nil {
panic(err)
}
printVersions := func(res *rivermigrate.MigrateResult) {
for _, version := range res.Versions {
fmt.Printf("Migrated [%s] version %d\n", strings.ToUpper(string(res.Direction)), version.Version)
}
}
// Migrate to version 3. An actual call may want to omit all MigrateOpts,
// which will default to applying all available up migrations.
res, err := migrator.Migrate(ctx, rivermigrate.DirectionUp, &rivermigrate.MigrateOpts{
TargetVersion: 3,
})
if err != nil {
panic(err)
}
printVersions(res)
// Migrate down by three steps. Down migrating defaults to running only one
// step unless overridden by an option like MaxSteps or TargetVersion.
res, err = migrator.Migrate(ctx, rivermigrate.DirectionDown, &rivermigrate.MigrateOpts{
MaxSteps: 3,
})
if err != nil {
panic(err)
}
printVersions(res)
}
Output: Migrated [UP] version 1 Migrated [UP] version 2 Migrated [UP] version 3 Migrated [DOWN] version 3 Migrated [DOWN] version 2 Migrated [DOWN] version 1
- type Config
- type Direction
- type MigrateOpts
- type MigrateResult
- type MigrateVersion
- type Migration
- type Migrator
- func (m *Migrator[TTx]) AllVersions() []Migration
- func (m *Migrator[TTx]) ExistingVersions(ctx context.Context) ([]Migration, error)
- func (m *Migrator[TTx]) ExistingVersionsTx(ctx context.Context, tx TTx) ([]Migration, error)
- func (m *Migrator[TTx]) GetVersion(version int) (Migration, error)
- func (m *Migrator[TTx]) Migrate(ctx context.Context, direction Direction, opts *MigrateOpts) (*MigrateResult, error)
- func (m *Migrator[TTx]) MigrateTx(ctx context.Context, tx TTx, direction Direction, opts *MigrateOpts) (*MigrateResult, error)deprecated
- func (m *Migrator[TTx]) Validate(ctx context.Context, opts *ValidateOpts) (*ValidateResult, error)
- func (m *Migrator[TTx]) ValidateTx(ctx context.Context, tx TTx, opts *ValidateOpts) (*ValidateResult, error)
- type ValidateOpts
- type ValidateResult
This section is empty.
This section is empty.
This section is empty.
Config contains configuration for Migrator.
MigrateOpts are options for a migrate operation.
type MigrateResult struct {
Direction Direction
Versions []MigrateVersion
}
MigrateResult is the result of a migrate operation.
MigrateVersion is the result for a single applied migration.
Migration is a bundled migration containing a version (e.g. 1, 2, 3), and SQL for up and down directions.
Migrator is a database migration tool for River which can run up or down migrations in order to establish the schema that the queue needs to run.
New returns a new migrator with the given database driver and configuration. The config parameter may be omitted as nil.
Two drivers are supported for migrations, one for Pgx v5 and one for the built-in database/sql package for use with migration frameworks like Goose. See packages riverpgxv5 and riverdatabasesql respectively.
The function takes a generic parameter TTx representing a transaction type, but it can be omitted because it'll generally always be inferred from the driver. For example:
import "github.com/riverqueue/river/riverdriver/riverpgxv5"
import "github.com/riverqueue/rivermigrate"
...
dbPool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
// handle error
}
defer dbPool.Close()
migrator, err := rivermigrate.New(riverpgxv5.New(dbPool), nil)
if err != nil {
// handle error
}
AllVersions gets information on all known migration versions.
ExistingVersions gets the existing set of versions that have been migrated in the database, ordered by version.
ExistingVersionsTx gets the existing set of versions that have been migrated in the database, ordered by version.
This variant checks for existing versions in a transaction.
GetVersion gets information about a specific migration version. An error is returned if a versions is requested that doesn't exist.
Migrate migrates the database in the given direction (up or down). The opts parameter may be omitted for convenience.
By default, applies all outstanding migrations when moving in the up direction, but for safety, only one step when moving in the down direction. To migrate more than one step down, MigrateOpts.MaxSteps or MigrateOpts.TargetVersion are available. Setting MigrateOpts.TargetVersion to -1 will apply every available downstep so that River's schema is removed completely.
res, err := migrator.Migrate(ctx, rivermigrate.DirectionUp, nil)
if err != nil {
// handle error
}
Migrate migrates the database in the given direction (up or down). The opts parameter may be omitted for convenience.
By default, applies all outstanding migrations when moving in the up direction, but for safety, only one step when moving in the down direction. To migrate more than one step down, MigrateOpts.MaxSteps or MigrateOpts.TargetVersion are available. Setting MigrateOpts.TargetVersion to -1 will apply every available downstep so that River's schema is removed completely.
res, err := migrator.MigrateTx(ctx, tx, rivermigrate.DirectionUp, nil)
if err != nil {
// handle error
}
This variant lets a caller run migrations within a transaction. Postgres DDL is transactional, so migration changes aren't visible until the transaction commits, and are rolled back if the transaction rolls back.
Deprecated: Use Migrate instead. Certain migrations cannot be batched together in a single transaction, so this method is not recommended.
Validate validates the current state of migrations, returning an unsuccessful validation and usable message in case there are migrations that haven't yet been applied.
ValidateTx validates the current state of migrations, returning an unsuccessful validation and usable message in case there are migrations that haven't yet been applied.
This variant lets a caller validate within a transaction.
type ValidateOpts struct {
TargetVersion int
}
ValidateOpts are options for a validate operation.