Skip to content

diff command ​

The diff command calculates schema differences between two SQL sources and produces human-friendly plans and SQL to migrate the source to the target.

The --from option specifies the source schema, the current state you want to migrate from. This is typically a live database connection string, but can also be a file, directory, or URL.

The --to option specifies the target schema, the desired state you want to migrate to. This can also be a file, directory, URL, or connection string.

To put it simply:

  • --from = current/source schema (what you have now)
  • --to = target schema (what you want to achieve)

The diff command generates a plan to transform the source into the target.

Usage ​

bash
migrata diff --from <SOURCE> --to <TARGET>

Accepted SOURCE / TARGET Values ​

You can provide a wide range of input types for the --from and --to options:

TypeDescription
SQL stringInline SQL string
File pathPath to a .sql file
DirectoryDirectory containing .sql files (all files are collected)
HTTP URLURL to fetch SQL content from (HTTP response body is used)
Connection stringDatabase connection string (inspects a remote DB)

Options ​

OptionDescription
--fromSource schema to compare. (Required)
--toTarget schema containing proposed changes. (Required)
--include / --excludeGlob patterns to include/exclude entities (tables, views, etc) based on their fully qualified name
-o | --outDirectory to write generated migration files. When set, generated plans are persisted.
-p | --postfixAdds a custom postfix to the names of all generated migration files.
--formatDisplay format for schema diff and plans. Options: stacked, inline, table. (default: stacked)
--safe-castGenerate safe multi-step column changes using temporary columns to prevent data loss when modifying existing data.
--no-stylesDisable console styling (colors/emoji). Useful for CI or files.
--silentSuppress SQL parsing error messages.
--no-logsSuppress execution logs and progress output.
--log-fileOptional file to write execution logs to.
--approve / --abortAuto-approve (apply) or auto-abort plans. Conflicting flags are validated by the CLI.
--skip-lockDisable advisory locking during migrations (unsafe for concurrent runs).
--dev-imageDocker image repo & name to pull for local validation against an ephemeral database.
--answer <KEY=VALUE>Supply an answer to a planner prompt, e.g. --answer status:Cancelled=Pending. Repeatable for multiple answers. Enables non-interactive CI/CD workflows.

Diff Risk Classification ​

The diff command classifies each migration plan and displays a risk summary alongside the diff output. The classification helps you quickly assess the impact of each change:

  • Safe: No data loss risk (e.g., adding a new table, creating an index)
  • Warning: Potential risk (e.g., changing a column type, adding a constraint on existing data)
  • Destructive: High risk (e.g., dropping a column, removing a table)

Warnings and destructive changes are summarized separately with counts, so you can review and address high-risk operations before applying.

Impact Analysis ​

The diff command shows all impacted downstream components alongside each query plan, regardless of the display format. This allows you to see which database objects (views, functions, etc.) depend on the entities being modified, helping you assess the blast radius of your changes.

The impacted components panel lists each downstream dependency sorted by type and name, visible in both the stacked/inline views and the table format.

Local Dev-Database Validation ​

The --dev-image flag lets you validate schema changes against an ephemeral database before applying them to production. When set, the CLI:

  1. Pulls the specified Docker image
  2. Spins up a temporary container
  3. Applies your current schema to the dev database
  4. Runs the migration SQL against it
  5. Reports any runtime errors
  6. Shuts down and cleans up the container

This gives you confidence that your migration won't fail due to unexpected runtime errors.

bash
migrata diff \
  --from "postgresql://user:pass@host:5432/prod_db" \
  --to ./proposed.sql \
  --dev-image postgres:16-alpine

Pre-Supplying Answers with --answer ​

The --answer flag allows you to pre-supply responses to interactive planner prompts, enabling fully non-interactive CI/CD workflows. The format is KEY=VALUE and the flag can be repeated for multiple answers:

bash
migrata diff \
  --from "postgresql://user:pass@host:5432/prod_db" \
  --to ./proposed.sql \
  --answer "status:Cancelled=Pending" \
  --approve

Examples ​

Diff two local SQL files and print plans:

bash
migrata diff --from ./schema_v1.sql --to ./schema_v2.sql

While this will correctly generate a plan, it will fail to apply because the --from tag is just a file and not a live database

Inspect a live Postgres DB and create a plan with --safe-cast:

bash
migrata diff \
  --from "postgresql://user:pass@host:5432/src_db" \
  --to ./proposed.sql \
  --include "public*"
  --safe-cast

Use the --safe-cast option ​

When you find yourself making changes to columns filled with real customer data, I recommend using the --safe-cast flag to ensure the generated plans aren't destructive and completely safe.

For example this command will use this general approach to safely change your schema:

  • Add a new column with the desired data type (temporary column).
  • Update the new column with converted values from the old column (using a cast if needed).
  • Drop the old column from the table.
  • Rename the new column to the original column name.
  • Re-apply any constraints and indexes that were associated with the original column.