How to preview changes with a dry run¶
sync(..., dry_run=True) runs read, diff, accepted/rejected planning, SQL
compilation, and dependency resolution, then skips execution. Nothing in the
catalog changes. The report shows the plan, its exact compiled SQL, and every
pre-execution failure discoverable from the catalog snapshot it read; it cannot
predict a Databricks error that would occur only while executing SQL.
Run a dry run¶
report = engine.sync(customers, orders, dry_run=True)
A dry run never raises SyncFailedError, even when it finds a read, validation,
or foreign-key failure — the point is to return the complete preview report.
See what would change¶
report.render_diff() shows every table’s planned changes as +/-/~
blocks; report.render() shows the per-table statuses and any failures:
print(report.render_diff())
print(report.render())
For example, previewing creation of the customers declaration from the
getting-started tutorial produces:
DIFF
====
dev.silver.customers (CREATE)
columns
+ id Integer NOT NULL
+ name String
SYNC REPORT
===========
PLAN — no planned SQL executed
TABLE STATUS STATEMENTS DETAIL
dev.silver.customers SUCCESS 1 2 columns
1 table: 1 changed, 0 unchanged, 0 deferred, 0 failed (0.0s)
Elapsed time varies. sync returns the report object and neither renderer is
called automatically. The diff answers what would change; the report answers
whether the plan succeeded and how much SQL it contains.
Each table’s plan records the DDL actions compiled for that observed snapshot.
The execution field stays None on every table, because nothing ran.
Check a dry run programmatically¶
The result is the same SyncReport type a real run returns, so the same
inspection applies — see
how to handle sync failures. A useful CI
gate is “no failures”:
report = engine.sync(customers, orders, dry_run=True)
if report.has_failures:
raise SystemExit(report.render())
report.has_changes reports whether any table has a planned change, and
report.planned_sql_statements maps each table with a planned change to the
SQL preview compiled for the current snapshot; tables already in sync are
omitted. For a machine-readable view of the whole
run — status, planned actions, and SQL as plain JSON — call report.to_dict() (see
the run report schema). To turn a dry run into a
red/green pull-request check, see
how to gate schema changes in CI.
Dry run first, then apply¶
A dry run and a real run use the same declaration and decision pipeline, so the
natural deployment shape is: dry-run in CI to review the plan, then run the same
sync call without dry_run to apply it. The real run re-reads and re-plans
live state, so its actions can differ if drift appeared after the preview. It
can also report execution failures that no dry run can discover.
The CLI mirrors this shape: delta-engine plan in CI, then delta-engine apply with the same declaration reference from a write-capable job.