Skip to Content

gofasta migrate

Runs database migrations using the golang-migrate  tool against the SQL files under db/migrations/. Three subcommands: up applies pending migrations (with optional static analysis via --explain), down rolls back (interactive menu by default; flags for scripted use), and repair clears a dirty migration state.

Usage

gofasta migrate <subcommand> [flags]

Subcommands

SubcommandDescription
upApply all pending migrations
downRoll back applied migrations (menu by default; --all or --steps N for scripts)
repairClear a dirty migration state after a manual fix

gofasta migrate up

Applies every pending .up.sql migration under db/migrations/. Skips files that have already been recorded in schema_migrations.

Flags

FlagDefaultDescription
--explainfalseStatic analysis of every pending .up.sql — flags risky DDL (DROP COLUMN, ADD COLUMN NOT NULL without DEFAULT, blocking CREATE INDEX, RENAME COLUMN/TABLE, ALTER COLUMN TYPE). Never opens a DB connection. Pairs with --strict in CI.
--strictfalseWith --explain: exit non-zero when any high-severity warning fires. CI gate to block risky migrations before they merge.

Examples

# Standard: apply every pending migration. gofasta migrate up # Preview what would be applied + lint for risky patterns (no DB needed). gofasta migrate up --explain # Same, but fail the run in CI on any high-severity warning. gofasta migrate up --explain --strict --json

Risk classification (--explain)

PatternRiskSeverity
ALTER TABLE ... DROP COLUMNdata-losshigh
ADD COLUMN ... NOT NULL (no DEFAULT)lock-and-fill (table rewrite)high
CREATE INDEX without CONCURRENTLYlock-tablemedium (Postgres)
RENAME COLUMN / RENAME TABLEapp-incompatibilitymedium
ALTER COLUMN ... TYPElock-and-rewritehigh
DROP TABLEdata-losshigh
TRUNCATEdata-losshigh
ADD PRIMARY KEYlock-and-rewritehigh

gofasta migrate down

Rolls back applied migrations. With no flags and an interactive terminal, opens a menu offering single-step / all / specific-count rollback. Pass --all or --steps N to skip the menu for scripted use.

Flags

FlagDefaultDescription
--allfalseRoll back ALL applied migrations (destructive — prompts for confirmation unless --yes).
--steps0Roll back exactly N migrations (skips the menu; default 1 in non-interactive mode).
--yesfalseSkip the destructive-action confirmation prompt (use with --all in scripts/CI).

Examples

# Interactive: opens a menu. gofasta migrate down # Roll back one migration without prompt. gofasta migrate down --steps 1 # Roll back everything in CI/scripts. gofasta migrate down --all --yes

gofasta migrate repair

Clears a dirty migration state. golang-migrate marks the migrations table as “dirty” when an .up.sql fails partway through — subsequent migrate up runs refuse to proceed until the dirty flag is cleared. Use this command only after you’ve manually verified the database state.

Flags

FlagDefaultDescription
--revertfalseYou’ve manually undone the dirty migration; mark version N-1 as current.
--completefalseYou’ve manually finished the dirty migration; mark version N as current.
--force-1Mark schema_migrations.version = N directly (skips the dirty-state inspection). Use very carefully.
--yesfalseSkip the destructive-action confirmation prompt (use in scripts).

--revert, --complete, and --force are mutually exclusive — pick exactly one.

Examples

# Inspect first — `migrate repair` with no flags prints the current state. gofasta migrate repair # You undid the dirty migration by hand in psql — mark N-1 as current. gofasta migrate repair --revert # You finished the dirty migration by hand — mark N as current. gofasta migrate repair --complete # Force a specific version. No dirty-state check — use carefully. gofasta migrate repair --force 7 --yes

How It Works

gofasta migrate up|down shells out to the golang-migrate tool:

migrate -path db/migrations -database <url> up

The database URL is built from config.yaml’s database: block (driver, host, port, name, user, password, sslmode), with GOFASTA_DATABASE_* env-var overrides applied.

migrate repair writes to schema_migrations directly — no SQL replay, just metadata fixup.

Supported Databases

DriverNotes
postgresDefault
mysqlMultiStatements auto-enabled by the migrate driver
sqliteFile-based; no DSN host/port
sqlserverSQL Server (Linux container in dev)
clickhouseOLAP target; foundational migration ships only the users table (no triggers)

The driver is determined at gofasta new --driver <name> time and baked into config.yaml. See gofasta new --driver for the full per-driver story.

Database Configuration

config.yaml:

database: driver: postgres host: localhost port: "5432" name: myapp_dev user: postgres password: postgres sslmode: disable

Override via env: GOFASTA_DATABASE_HOST, GOFASTA_DATABASE_PORT, etc.

Migration File Format

Up:

-- db/migrations/000006_create_products.up.sql CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, price DECIMAL(10,2) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW(), deleted_at TIMESTAMP ); CREATE INDEX idx_products_deleted_at ON products(deleted_at);

Down:

-- db/migrations/000006_create_products.down.sql DROP TABLE IF EXISTS products;

Generate new migration pairs via gofasta g migration or as part of gofasta g scaffold.

Last updated on