CLI Reference
plan

schemahero plan

Compare your table definitions to a database and output the SQL needed to synchronize them.

Usage

schemahero plan [flags]

Examples

Basic Usage

schemahero plan \
  --driver postgres \
  --uri "postgres://user:pass@localhost:5432/mydb?sslmode=disable" \
  --spec-file ./schema/users.yaml

Output:

create table "users" (
  "id" uuid default gen_random_uuid(),
  "email" varchar (255) not null,
  "created_at" timestamp default now(),
  primary key ("id")
);

Plan a Directory

schemahero plan \
  --driver postgres \
  --uri "$DATABASE_URL" \
  --spec-file ./schema/

Processes all YAML files in the directory recursively.

Save to File

schemahero plan \
  --driver postgres \
  --uri "$DATABASE_URL" \
  --spec-file ./schema/ \
  --out migrations.sql

Multiple Spec Files

schemahero plan \
  --driver postgres \
  --uri "$DATABASE_URL" \
  --spec-file ./schema/base/ \
  --spec-file ./schema/extensions/

MySQL

schemahero plan \
  --driver mysql \
  --uri "user:pass@tcp(localhost:3306)/mydb" \
  --spec-file ./schema/

CockroachDB

schemahero plan \
  --driver cockroachdb \
  --uri "postgres://user:pass@localhost:26257/mydb?sslmode=disable" \
  --spec-file ./schema/

SQLite

schemahero plan \
  --driver sqlite \
  --uri "./data/myapp.db" \
  --spec-file ./schema/

Flags

FlagTypeDescription
--driverstringDatabase driver: postgres, mysql, cockroachdb, sqlite, cassandra, timescale
--uristringDatabase connection URI
--spec-filestringPath to YAML file or directory (can be repeated)
--outstringOutput file (default: stdout)
--overwriteboolOverwrite output file if exists (default: true)

Output

When there are changes:

alter table "users" add column "phone" varchar (20);
create index "idx_users_phone" on "users" ("phone");

When no changes needed:

(empty output)

Exit Codes

CodeMeaning
0Success (even if no changes)
1Error (connection failed, invalid YAML, etc.)

Common Patterns

CI Check

PLAN=$(schemahero plan --driver postgres --uri "$DB" --spec-file ./schema/)
if [ -n "$PLAN" ]; then
  echo "Schema changes detected:"
  echo "$PLAN"
fi

Validate Without Database

# Syntax check only (uses fake URI)
schemahero plan \
  --driver postgres \
  --uri "postgres://x:x@localhost/x" \
  --spec-file ./schema/ \
  --dry-run

Pipe to Apply

schemahero plan --driver postgres --uri "$DB" --spec-file ./schema/ | \
schemahero apply --driver postgres --uri "$DB" --ddl /dev/stdin

Or with process substitution:

schemahero apply \
  --driver postgres \
  --uri "$DB" \
  --ddl <(schemahero plan --driver postgres --uri "$DB" --spec-file ./schema/)