Skip to content

CLI Commands

Arael Espinosa edited this page Apr 7, 2026 · 5 revisions

CLI Commands

All commands share the same base options and accept a config file path.

Common Options

Option Short Default Description
--config <PATH> -c config.yaml Path to config file
--dry-run false Print what would run, no changes
--skip-validation false Skip schema validation before executing
--strict false Treat warnings as errors and abort
--log-level <LEVEL> info debug | info | warn | error
--verbose -v false Shorthand for --log-level debug
--no-color false Disable ANSI colors (also via NO_COLOR env var)
--print-args false Print full pg_dump/pg_restore argument list
--preflight-only false Run pre-flight checks and exit without migrating
--gcp-logs false Output structured JSON for Cloud Logging (auto-enabled in Cloud Run via K_SERVICE)
--log-file <PATH> — Also write structured logs to a file
--dump-dir <PATH> — Persist the pg_dump directory at this path; reuse it on the next run if valid (skips re-dump). Overrides dump.dump_dir in config.

Execution Order

Every run and migrate command follows this fixed order:

1. Load & validate config
2. Pre-flight checks        (tool availability, connectivity, disk space, privileges, locks)
   └─ --preflight-only → exit here
3. Schema validation        (unless --skip-validation)
4. Migration                (pg_dump + pg_restore + post-migration table verification)
5. Sanitization             (run only — not migrate)

Pre-flight Checks

Run automatically before every migration. Check results are printed to the console and written to the log file/GCP if configured.

Check What it verifies
Tool availability pg_dump --version and pg_restore --version — aborts if either is missing from PATH
Source connectivity TCP/socket connection to source DB
Target connectivity TCP/socket connection to target DB
Disk space pg_database_size on source vs available space on the dump drive — requires 1.2× source size
Source table access has_table_privilege(SELECT) on all public tables — respects role grants (pg_read_all_data)
Source sequence access has_sequence_privilege(SELECT) on all public sequences — required for pg_dump
Target write access has_table_privilege(INSERT) on all public tables — skipped if target is empty
Idle-in-transaction Warns if connections are idle in transaction (may block pg_dump)
Ungranted locks Warns if there is active lock contention on source

To grant full read access on source (PostgreSQL 14+):

GRANT pg_read_all_data TO "db-migrator";

To grant full write access on target:

GRANT pg_write_all_data TO "db-migrator";

Use --preflight-only to run checks and exit without touching data:

db-migrator run --config config.yaml --preflight-only

run

Runs the full pipeline: pre-flight → schema validation → dump → restore → sanitize.

db-migrator run --config config.yaml
db-migrator run --config config.yaml --dry-run
db-migrator run --config config.yaml --strict --verbose
db-migrator run --config config.yaml --preflight-only

migrate

Pre-flight → schema validation → dump + restore only (no sanitization).

db-migrator migrate --config config.yaml

Useful when you want to run sanitization separately or have a custom post-processing step.


sanitize

Apply sanitization rules to the target database only. Assumes data is already present.

db-migrator sanitize --config config.yaml
db-migrator sanitize --config config.yaml --dry-run

With --dry-run, prints the generated UPDATE statements without executing them.


validate

Validate the config file and check all referenced tables and columns exist in the source database. No data is read or written.

db-migrator validate --config config.yaml

Checks performed:

  • Config structure and required fields
  • Environment variables are set
  • Tables exist in source DB
  • Columns exist and match expected types
  • null_value strategy used only on nullable columns
  • Warnings for primary key modifications
  • Warnings for empty tables

Exit code 0 = valid. Exit code 1 = errors found.

Use --strict to fail on warnings as well.


Logging

db-migrator uses two separate output channels:

Channel When active Format
Console (AnsiConsole) Always (local mode) Clean colored output, no timestamps
File (--log-file) When --log-file <path> is set [HH:mm:ss LVL] message — includes all events + pg_dump progress at debug level
GCP (--gcp-logs) When flag set or K_SERVICE env var present Compact JSON (CLEF) to stdout — AnsiConsole suppressed, Serilog owns stdout

In GCP/Cloud Run mode, console output is suppressed entirely so Cloud Logging only receives well-structured JSON lines. All events that appear in the console (pre-flight results, migration progress, errors) are mirrored as structured log entries.

# Write a full log file alongside normal console output
db-migrator run --config config.yaml --log-file /var/log/migration.log

# GCP structured JSON (auto-enabled in Cloud Run)
db-migrator run --config config.yaml --gcp-logs

# Debug: see pg_dump progress in log file
db-migrator run --config config.yaml --verbose --log-file debug.log

Exit Codes

Code Meaning
0 Success
1 Validation error or execution failure

Note: pg_restore exits with code 1 when using --clean against a fresh target database (the DROP IF EXISTS statements fail because objects do not exist yet). db-migrator treats this as a non-fatal warning — the restore completes successfully and a ⚠ line is printed to the console. A true failure (missing tables, auth errors, corrupt dump) will also exit 1 but will include a descriptive error message and abort the run.

Clone this wiki locally