Skip to content

Migration Workflow ​

The core workflow has two stages: inspect the source schema, then diff against your target. The diff command does the heavy lifting: it generates the migration plan in memory, presents it for review, and can apply it directly without ever writing a file.

1. Inspect the Source ​

Capture the current state of a live database into local SQL files:

bash
migrata schema inspect \
  --from "postgresql://user:pass@host:5432/prod_db" \
  --to ./schemas/current

This writes all DDL (tables, views, functions, enums, partitions, etc.) into a directory structure on your machine.

2. Prepare the Target ​

Make the desired schema changes by editing the SQL files directly. For example, add a new column to ./schemas/target/public/users.sql:

sql
CREATE TABLE public.users (
    id SERIAL PRIMARY KEY,
    email TEXT NOT NULL,
    name TEXT NOT NULL,
    created_at TIMESTAMPTZ DEFAULT now()
);

You can also point --to at a different live database, a URL, or a single SQL string.

3. Diff, Review, and Apply ​

Compare the two schemas and review the generated migration plan:

bash
migrata diff \
  --from ./schemas/current \
  --to ./schemas/target

If the plan shows unexpected changes, check that you are comparing the correct schemas. Use --include "public*" to restrict the comparison to your main schema and avoid system schemas.

The output shows:

  • Schema Overview: a table comparing entity counts (tables, partitions, indexes, etc.) between sources
  • Query Plans: the SQL statements that will be executed for each change
  • Risk Summary: warnings and destructive changes are highlighted separately
  • Impacted Components: downstream objects (views, functions) that depend on modified entities

After reviewing the plan, choose Apply to execute it in memory against your database, or Abort to exit without changes. Use --approve to skip the prompt and apply immediately, or --abort to auto-abort.

Use --format table to see all plans and impacted components in a compact table layout.

Use --answer to pre-supply responses to interactive prompts for fully automated runs.

Optional: Persist Plans and Apply Separately ​

For workflows that need an audit trail, peer review, or deferred execution, persist the generated plan to a file:

bash
migrata diff \
  --from ./schemas/current \
  --to ./schemas/target \
  -o ./migrations \
  -p "add_email_column"

This writes a timestamped file like ./migrations/1740612345_add_email_column.sql without applying anything.

Later, apply the saved file with the apply command:

bash
migrata apply \
  --from ./migrations/1740612345_add_email_column.sql \
  --to "postgresql://user:pass@host:5432/prod_db"

You can also validate against an ephemeral database before applying to production:

bash
migrata diff \
  --from ./schemas/current \
  --to ./schemas/target \
  --dev-image postgres:16-alpine \
  --approve

The CLI spins up a temporary Docker container, applies the current schema, runs the migration, and reports any runtime errors. See the Dev-Database Validation guide for details.

Quick Reference ​

StepCommandKey Flags
Inspectmigrata schema inspect--from, --to, --include
Diff & Applymigrata diff (with --approve)--from, --to, --format, --safe-cast
Validatemigrata diff--dev-image
Persist Planmigrata diff-o, -p / --postfix
Deferred Applymigrata apply--from, --to, --skip-lock