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
| Subcommand | Description |
|---|---|
up | Apply all pending migrations |
down | Roll back applied migrations (menu by default; --all or --steps N for scripts) |
repair | Clear 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
| Flag | Default | Description |
|---|---|---|
--explain | false | Static 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. |
--strict | false | With --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 --jsonRisk classification (--explain)
| Pattern | Risk | Severity |
|---|---|---|
ALTER TABLE ... DROP COLUMN | data-loss | high |
ADD COLUMN ... NOT NULL (no DEFAULT) | lock-and-fill (table rewrite) | high |
CREATE INDEX without CONCURRENTLY | lock-table | medium (Postgres) |
RENAME COLUMN / RENAME TABLE | app-incompatibility | medium |
ALTER COLUMN ... TYPE | lock-and-rewrite | high |
DROP TABLE | data-loss | high |
TRUNCATE | data-loss | high |
ADD PRIMARY KEY | lock-and-rewrite | high |
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
| Flag | Default | Description |
|---|---|---|
--all | false | Roll back ALL applied migrations (destructive — prompts for confirmation unless --yes). |
--steps | 0 | Roll back exactly N migrations (skips the menu; default 1 in non-interactive mode). |
--yes | false | Skip 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 --yesgofasta 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
| Flag | Default | Description |
|---|---|---|
--revert | false | You’ve manually undone the dirty migration; mark version N-1 as current. |
--complete | false | You’ve manually finished the dirty migration; mark version N as current. |
--force | -1 | Mark schema_migrations.version = N directly (skips the dirty-state inspection). Use very carefully. |
--yes | false | Skip 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 --yesHow It Works
gofasta migrate up|down shells out to the golang-migrate tool:
migrate -path db/migrations -database <url> upThe 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
| Driver | Notes |
|---|---|
postgres | Default |
mysql | MultiStatements auto-enabled by the migrate driver |
sqlite | File-based; no DSN host/port |
sqlserver | SQL Server (Linux container in dev) |
clickhouse | OLAP 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: disableOverride 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.