Run report schema¶
SyncReport.to_dict() projects a whole run as plain, JSON-serialisable data —
dict, list, str, int, bool, and None only, so
json.dumps(report.to_dict()) works directly. It is the machine-readable view
of a run, for CI gates, run-history persistence, and structured logging. The
human-readable views are render_report and render_diff.
TableRunReport.to_dict() projects a single table’s record, the same object
that appears in the run-level tables list.
Stability¶
The fields and enumerated values below are a public contract, versioned by
schema_version. Adding a field is backwards-compatible; renaming or removing
one, or renaming an enumerated value, is a breaking change and increments
schema_version. The projection is deterministic: tables appear in run order,
and changes and statements in action-plan order, so two projections of the same
report compare equal — successive dry-run outputs can be diffed.
Version 2 renamed the planning-phase status from VALIDATION_FAILED to
PLANNING_FAILED and the corresponding failure phase from VALIDATION to
PLANNING.
Run-level fields¶
SyncReport.to_dict() returns:
Field |
Type |
Meaning |
|---|---|---|
|
|
Version of this payload schema; currently |
|
|
ISO 8601 timestamp when the run began |
|
|
ISO 8601 timestamp when the run ended |
|
|
Whether execution was skipped |
|
|
True if any table has a planned change |
|
|
True if any table failed a phase |
|
|
Per-table records, in run order (see below) |
Table-level fields¶
Each entry in tables, and the whole of TableRunReport.to_dict():
Field |
Type |
Meaning |
|---|---|---|
|
|
Dotted, unquoted qualified name, e.g. |
|
|
A |
|
|
True if this table has a planned change |
|
|
True if this table failed a phase |
|
|
Summaries of the planned changes, in plan order (see below) |
|
|
Full compiled DDL the plan lowers to, in order |
|
|
Failure records, in phase order (see below) |
|
|
Execution counts, or |
Change records¶
Each entry in changes summarises part of a planned change, derived from the
same interpretation the text renderers use. They are human-oriented summaries,
not one record per plan action (a table creation expands into several), and
not a complete description of the change — the authoritative, complete
description is planned_sql_statements:
Field |
Type |
Meaning |
|---|---|---|
|
|
Change category: |
|
|
|
|
|
What the change targets, e.g. a column name or |
|
|
Extra detail, e.g. |
Failure records¶
Each entry in failures:
Field |
Type |
Meaning |
|---|---|---|
|
|
The phase that produced it: |
|
|
The concrete failure class name, e.g. |
|
|
The rendered failure message |
Execution record¶
When a table executed, execution is:
Field |
Type |
Meaning |
|---|---|---|
|
|
Statements that ran successfully |
|
|
Statements planned ( |
It is None for a dry run and for any table skipped by an earlier-phase
failure. Execution runs statement by statement and stops at the first
failure, so applied < total means the trailing statements were never
attempted.
The planned SQL property¶
Alongside the projection, SyncReport.planned_sql_statements is a
dict[str, tuple[str, ...]] mapping each table’s dotted name to its compiled
statements, omitting tables with no planned change. It is the same statement
text that appears per table under planned_sql_statements in to_dict().
Planned is not executed: a table blocked after planning (for example by a
foreign-key dependency failure) still reports the SQL its plan compiles to.
Whether the statements ran is answered by execution and has_failures.
See how to gate schema changes in CI for the projection in use.