Skip to content

CLI Reference

CommandPurpose
pgmt initInitialize new project
pgmt applyApply schema to dev database
pgmt diffPreview what apply would do
pgmt migrate newGenerate migration
pgmt migrate updateRegenerate migration after changes
pgmt migrate applyApply migrations to target database
pgmt migrate provisionSet up a new database from a baseline
pgmt migrate statusShow migration status
pgmt migrate validateValidate migrations match schema
pgmt migrate diffDetect drift in target database
pgmt migrate baselineCreate baseline / consolidate migrations
pgmt migrate baseline listList baselines
pgmt debug dependenciesAnalyze object dependencies

Available for all commands:

-h, --help # Show help
-V, --version # Show version
--config-file <FILE> # Config file (default: pgmt.yaml)
-v, --verbose # Verbose output
-q, --quiet # Suppress non-essential output
--debug # Debug output

Database connection flags (--dev-url, --shadow-url, --target-url) appear only on commands that actually connect to that database — a command’s --help doubles as documentation of which databases it touches. Each flag overrides the matching PGMT_* environment variable, which overrides pgmt.yaml. Everything else (directories, object scoping, migration settings) is project configuration and lives in pgmt.yaml only.


Initialize a new pgmt project. Can be re-run to update an existing configuration.

pgmt init [OPTIONS]

Options:

--dev-url <URL> # Database URL (required)
--create-baseline # Create baseline from existing database
--no-baseline # Skip baseline creation
--no-import # Skip import (empty project)
--defaults # Use defaults for all prompts
--schema-dir <DIR> # Schema directory name (default: "schema")
--migrations-dir <DIR> # Migrations directory name (default: "migrations")
--baselines-dir <DIR> # Baselines directory name (default: "schema_baselines")
--auto-shadow # Use auto shadow database
--shadow-pg-version <VER> # PostgreSQL version for auto shadow (e.g., "14", "15", "16")
--shadow-image <IMAGE> # Shadow Docker image (e.g. "postgis/postgis:16-3.5"); conflicts with --shadow-pg-version/--auto-shadow
--baseline-description <TEXT> # Custom description for the created baseline
--shadow-platform <PLATFORM> # Platform for the shadow image (e.g. "linux/amd64") for single-arch images
--shadow-url <URL> # Use an external shadow database at this URL (skips Docker)
--roles-file <PATH> # Path to roles file (default: auto-detect roles.sql)
--fresh # Force fresh init (overwrite existing config)

Re-initialization:

When run in a directory with an existing pgmt.yaml, you’ll be prompted to:

  • Update - Modify existing config (shows current values as defaults)
  • Fresh - Start over with new configuration
  • Cancel - Keep current configuration

In Update mode, anything you’ve configured by hand and init doesn’t ask about — shadow environment and container_name, objects scoping, migration settings — is preserved in the regenerated file, and the prompts are pre-filled from your current values.

Use --fresh to skip this prompt and always overwrite.

Config-first setup (advanced):

pgmt init only asks the essentials; pgmt.yaml is the full interface (see the configuration reference). If your setup needs options the wizard doesn’t cover — a custom shadow image with environment variables, schema scoping for a managed platform — write pgmt.yaml first, then run pgmt init and choose Update: the import and baseline workflow runs under your configuration. The shadow clean during import respects objects.include.schemas, so platform-managed schemas are preserved.

Examples:

# Interactive (recommended)
pgmt init --dev-url postgres://localhost/myapp_dev
# Import existing database with baseline
pgmt init --dev-url postgres://localhost/existing_db --create-baseline
# Empty project
pgmt init --defaults --no-import
# Custom directory structure
pgmt init --dev-url postgres://localhost/myapp_dev \
--schema-dir db/schema \
--migrations-dir db/migrations \
--baselines-dir db/baselines
# Specify PostgreSQL version for shadow database
pgmt init --dev-url postgres://localhost/myapp_dev --auto-shadow --shadow-pg-version 14
# Extension-heavy schema (PostGIS) on an arm64 host: use an image that includes
# the extension, and run it under emulation since postgis/postgis is amd64-only
pgmt init --dev-url postgres://localhost/gis_db \
--shadow-image postgis/postgis:16-3.5 \
--shadow-platform linux/amd64
# Re-initialize with fresh config
pgmt init --dev-url postgres://localhost/newdb --fresh

Apply schema files to the development database.

pgmt apply [OPTIONS]

Options:

--dry-run # Preview changes without applying
--force # Apply all changes without confirmation
--safe-only # Apply only safe changes, skip destructive
--require-approval # Fail if destructive changes exist
--watch # Watch for file changes
--dev-url <URL> # Development database [env: PGMT_DEV_URL]
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Default behavior:

  • In terminal (interactive): Auto-apply safe changes, prompt for destructive
  • In CI/pipes (non-interactive): Fail with exit code 2 if destructive changes exist

Exit codes:

  • 0: Success (or no changes needed)
  • 1: Error
  • 2: Destructive changes exist (in --require-approval mode or non-interactive)

Examples:

pgmt apply # Interactive - prompts when needed
pgmt apply --watch # Watch mode - shows which file changed
pgmt apply --dry-run # Preview only
pgmt apply --force # Apply all without prompts
pgmt apply --safe-only # Skip destructive changes
# CI/CD usage:
pgmt apply # Fails (exit 2) if destructive ops exist
pgmt apply --force # Forces all changes in CI

Compare schema files against the development database. Shows what pgmt apply would do.

pgmt diff [OPTIONS]

Options:

--format <FORMAT> # detailed | summary | sql | json
--output-sql <FILE> # Save SQL to file
--dev-url <URL> # Development database [env: PGMT_DEV_URL]
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt diff # Detailed comparison
pgmt diff --format summary # Quick overview
pgmt diff --format sql # SQL to sync

Exit codes: 0 = no differences, 1 = differences found


Generate a new migration based on schema changes.

pgmt migrate new [DESCRIPTION] [OPTIONS]

Options:

--create-baseline # Create baseline alongside migration
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt migrate new "add users table"
pgmt migrate new "v2.0 release" --create-baseline
pgmt migrate new # Interactive (prompts for description)

Regenerate a migration after schema changes or when your branch is behind.

pgmt migrate update [VERSION] [OPTIONS]

Arguments:

VERSION # Migration version (e.g., 1234567890, V1234567890, or partial 123456)
# If omitted, updates the latest migration

Options:

--dry-run # Preview without updating
--backup # Create .bak file before updating
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt migrate update 1734567890 # Update specific migration (V prefix also accepted)
pgmt migrate update --dry-run # Preview
pgmt migrate update --backup # Update with backup

Note: This regenerates the migration from scratch. Manual edits will be lost.


Apply migrations to a target database.

pgmt migrate apply [OPTIONS]

Options:

--target-url <URL> # Target database [env: PGMT_TARGET_URL] (required)

Examples:

pgmt migrate apply --target-url postgres://prod/myapp
pgmt migrate apply # Uses target_url from pgmt.yaml

Set up a new database from a baseline plus its post-baseline migrations. Use this for a fresh environment (demo, staging, preview, disaster recovery); migrate apply only maintains a database that’s already established.

pgmt migrate provision [OPTIONS]

Options:

--target-url <URL> # Target database [env: PGMT_TARGET_URL] (required)
--dry-run # Preview what would be applied, without changing the database

What it does, based on the target’s state:

  • Empty + a baseline exists: applies the baseline, records it, then applies the migrations after it.
  • No baseline in the repo: replays all migrations from scratch.
  • Already provisioned: applies any pending migrations (like migrate apply).

If the baseline collides with objects already in the target, the apply fails atomically (Postgres reports relation "x" already exists) and nothing is left behind.

Examples:

pgmt migrate provision --target-url postgres://localhost/demo
pgmt migrate provision --target-url postgres://localhost/demo --dry-run

Show which migrations the development database has applied.

pgmt migrate status [OPTIONS]

Options:

--dev-url <URL> # Development database [env: PGMT_DEV_URL]

Example output:

Applied:
1734500000 - create_users (applied: 2024-12-18 10:00)
1734510000 - add_posts (applied: 2024-12-18 11:00)
Pending:
1734520000_add_comments.sql

Validate that migrations produce the expected schema. Use in CI to catch missing migrations.

pgmt migrate validate [OPTIONS]

Options:

--format <FORMAT> # human | json
--verbose # Detailed output
--ignore-migrations <NAMES> # Comma-separated migrations to skip during validation
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt migrate validate
pgmt migrate validate --format json

Exit codes: 0 = valid, 1 = mismatch


Detect drift between schema files and target database.

pgmt migrate diff [OPTIONS]

Options:

--format <FORMAT> # detailed | summary | sql | json
--output-sql <FILE> # Save remediation SQL to file
--target-url <URL> # Target database [env: PGMT_TARGET_URL] (required)
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt migrate diff --target-url postgres://prod/myapp
pgmt migrate diff --format sql --output-sql fix-drift.sql

Exit codes: 0 = no drift, 1 = drift detected


Create a baseline from current schema files. By default, deletes all existing migrations and old baselines since the baseline supersedes them.

pgmt migrate baseline [OPTIONS]

Options:

--force # Skip baseline validation
--keep-migrations # Don't delete old migrations
--dry-run # Preview what would happen
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt migrate baseline # Baseline + clean up migrations
pgmt migrate baseline --keep-migrations # Baseline only, keep migrations
pgmt migrate baseline --dry-run # Preview what would be deleted

List existing baselines.

pgmt migrate baseline list

Analyze object dependencies from both PostgreSQL introspection and -- require: headers. Useful for troubleshooting dependency ordering issues.

pgmt debug dependencies [OPTIONS]

Options:

--format <FORMAT> # json | text (default: json)
--object <NAME> # Filter to specific object
--shadow-url <URL> # Shadow database [env: PGMT_SHADOW_URL]

Examples:

pgmt debug dependencies # JSON output
pgmt debug dependencies --format text # Human-readable
pgmt debug dependencies --object public.users # Filter to one object

Output includes:

  • All tracked objects and their types
  • File-to-object mappings (which file defines which objects)
  • File dependencies from -- require: headers
  • Dependency graph showing what each object depends on

Manage configuration.

pgmt config get <KEY> # Get value
pgmt config set <KEY> <VALUE> # Set value
pgmt config list # List all values
pgmt config validate # Validate config file

Examples:

pgmt config get databases.dev
pgmt config set databases.dev postgres://localhost/myapp
pgmt config list --format json

Connection variables override pgmt.yaml and are themselves overridden by the matching CLI flag (flag > env > file):

PGMT_DEV_URL # Development database URL
PGMT_SHADOW_URL # Shadow database URL (instead of auto Docker)
PGMT_TARGET_URL # Target (production/staging) database URL
PGMT_KEEP_SHADOW_ON_FAILURE # Keep the shadow container alive after a startup
# failure for debugging (any non-empty value)
RUST_LOG # Log filter (e.g. RUST_LOG=debug)

General:

CodeMeaning
0Success
1Error (general)

Command-specific:

CommandCodeMeaning
pgmt apply2Destructive operations exist (in non-interactive/--require-approval mode)
pgmt diff1Differences detected
pgmt migrate diff1Drift detected
pgmt migrate validate1Validation failed