delta_engine¶
delta-engine: declarative schema management for Delta Lake tables.
This is the curated runtime entry point. The preferred user imports are:
from delta_engine.schema import DeltaTable, Column, Integer
from delta_engine.databricks import build_spark_engine
from delta_engine import Engine
Only backend-neutral runtime types live here. Schema declarations belong in
delta_engine.schema and Databricks helpers belong in delta_engine.databricks.
Submodules¶
Attributes¶
Exceptions¶
Raised when one sync receives two definitions for the same table. |
|
Raised when one or more tables failed during sync. |
Classes¶
High-level orchestrator to plan and execute changes. |
|
Details about a statement that failed while executing. |
|
The sync phase that produced a failure. Ordered so the earliest wins. |
|
A foreign key constraint that could not be applied, failing its whole table. |
|
Failure reading current catalog state for a table. |
|
Aggregate report for a run across all tables. |
|
What happened to one table's intended catalog change within a run. |
|
Frozen public record of one table's sync run. |
|
High-level status of a table's sync run. |
|
Description of a validation rule failure. |
Functions¶
|
Render every table's planned changes as +/-/~ blocks, under a DIFF title. |
|
Render the run: title, optional dry-run banner, status grid, failures section, footer. |
Package Contents¶
- exception DuplicateTableDefinitionError(qualified_name: delta_engine.domain.model.QualifiedName)¶
Bases:
ValueErrorRaised when one sync receives two definitions for the same table.
- qualified_name¶
- class Engine(reader: delta_engine.application.ports.CatalogStateReader, executor: delta_engine.application.ports.PlanExecutor)¶
High-level orchestrator to plan and execute changes.
The engine coordinates reading current state from a catalog, computing a diff of desired vs observed state, accepting or rejecting that diff at the validated planning boundary, resolving FK dependencies with full failure context, and executing accepted plans using the provided adapters.
- reader¶
- executor¶
- sync(*tables: delta_engine.application.ports.DesiredTableSource, dry_run: bool = False) delta_engine.application.report.SyncReport¶
Synchronize all registered tables to their desired state.
Runs lower → resolve → plan → execute → report. Resolution orders the tables dependency-first with their static facts, the plan pass takes each table through its read-only steps (read, plan, compile) and freezes one complete
TableRun, execution attaches attempted statement results to the tables it reaches, and assembly derives dependency blocking from the edges.A table that fails an early phase carries that failure on its run and is skipped by execution; it is still included in the report.
- Parameters:
*tables – The table specifications to synchronize. Duplicate qualified names raise
DuplicateTableDefinitionErrorbefore any phase runs.dry_run – When True, stop after the plan pass and attempt no statements (zero catalog mutations). No table retains attempted statement results, while its
planstill records the actions compiled from the observed snapshot. Blocking is derived rather than executed, so a dependent of a failed table still reports BLOCKED_BY_FAILED_DEPENDENCY in the preview. The report is returned instead of raisingSyncFailedErrorwhen a table fails.
- Returns:
The aggregate
SyncReportfor the run.- Raises:
DuplicateTableDefinitionError – If two table specifications have the same qualified name. No phase has run when this is raised.
SyncFailedError – On a real run (
dry_run=False), if any table fails to read, validate, resolve foreign keys, or execute. The report is available on the exception’sreportattribute. A dry run never raises.
- class ExecutionFailure¶
Details about a statement that failed while executing.
- phase: ClassVar[FailurePhase]¶
- statement_index: int¶
- exception_type: str¶
- message: str¶
- statement: str¶
- format_lines() tuple[str, Ellipsis]¶
- headline() str¶
- property statement_number: int¶
The failing statement’s one-based display position.
statement_indexremains zero-based so it indexes the compiled statements. Only the reader-facing number shifts, making “statement 3” agree with a report-grid progress count of “2/3”.
- type Failure = ReadFailure | ValidationFailure | ExecutionFailure | ForeignKeyFailure¶
- class FailurePhase¶
Bases:
enum.IntEnumThe sync phase that produced a failure. Ordered so the earliest wins.
- FOREIGN_KEY = 1¶
- READ = 2¶
- PLANNING = 3¶
- EXECUTION = 4¶
- class ForeignKeyFailure¶
A foreign key constraint that could not be applied, failing its whole table.
- phase: ClassVar[FailurePhase]¶
- table: delta_engine.domain.model.QualifiedName¶
- local_columns: delta_engine.domain.collection_types.ListOrTuple[str]¶
- references: delta_engine.domain.model.QualifiedName¶
- reason: ForeignKeyFailureReason¶
- format_lines() tuple[str, Ellipsis]¶
- headline() str¶
- class ReadFailure¶
Failure reading current catalog state for a table.
- phase: ClassVar[FailurePhase]¶
- exception_type: str¶
- message: str¶
- format_lines() tuple[str, Ellipsis]¶
- headline() str¶
- exception SyncFailedError(report: delta_engine.application.report.SyncReport)¶
Bases:
ExceptionRaised when one or more tables failed during sync.
- report¶
- class SyncReport¶
Aggregate report for a run across all tables.
- started_at: datetime.datetime¶
- ended_at: datetime.datetime¶
- dry_run: bool = False¶
- classmethod assemble(*, started_at: datetime.datetime, ended_at: datetime.datetime, table_runs: delta_engine.domain.collection_types.ListOrTuple[TableRun], dry_run: bool) Self¶
Assemble the run report, deriving dependency blocking from the graph.
Folds the blocking rule over the runs in dependency order: a table that did not converge — own failures, or a dependency that did not — marks its name, and a sound table its resolution reports as blocked is replaced by a copy carrying those failures. The run recorded nothing about blocking; this projection is where the consequence becomes visible, dry and real runs alike.
- property has_failures: bool¶
Return True if any table failed in the run.
- property has_changes: bool¶
True if any table’s plan holds actions.
States facts about planned changes only: a table that failed validation contributes failures, not changes. The CI gate idiom is
report.has_failures or report.has_changes.
- property table_change_states: tuple[TableChangeState, Ellipsis]¶
Catalog change state for each table run, in run order.
- property duration_seconds: float¶
Wall-clock seconds the run took, start to end.
- property counts: RunCounts¶
Per-outcome table counts.
A table that failed counts as failed whatever else it planned: the planned changes were not applied, so reporting them as changes would overstate what the run achieved.
- property planned_sql_statements: dict[str, tuple[str, Ellipsis]]¶
Dotted table name → the SQL its plan compiles to; no-op tables omitted.
- property failures_by_table: dict[delta_engine.domain.model.QualifiedName, tuple[delta_engine.application.failures.Failure, Ellipsis]]¶
Mapping of qualified table name to its failures (if any).
- render() str¶
Render the run’s status, failures, and summary as human-readable text.
- render_diff() str¶
Render every table’s planned changes as human-readable text.
- to_dict() dict[str, Any]¶
Project the whole run as plain, JSON-serialisable data; tables in run order.
- class TableChangeState¶
Bases:
enum.StrEnumWhat happened to one table’s intended catalog change within a run.
- NOT_PLANNED = 'not planned'¶
- DEFERRED = 'deferred'¶
- UNCHANGED = 'unchanged'¶
- PLANNED = 'planned'¶
- NOT_APPLIED = 'not applied'¶
- PARTIALLY_APPLIED = 'partially applied'¶
- APPLIED = 'applied'¶
- class TableRun¶
Frozen public record of one table’s sync run.
Born complete at the engine’s plan pass: everything the table can know alone — its resolution, read, planning outcome, and compiled SQL — is fixed at construction, in lifecycle field order, and the trailing fields default to their not-applicable state. The two facts that depend on other tables are attached afterwards as functional updates:
executionby the execute walk,blocked_failuresat assembly. A run without execution is a legitimate terminal state (a dry run, a blocked table, a no-op plan, a deferred absent table), not an unfinished one.planisNonewhen reading or planning failed; a successfully planned no-op retains an empty, target-bearing plan.compiledis populated on dry and real runs so the accepted plan and its statements remain inspectable even when execution is skipped or blocked.blocked_failuresis the derived consequence of other tables’ fates, baked in at assembly — a blocked table records no execution outcome of its own.diffis derived from the planning outcome, which retains the complete set of differences it planned from — actions and unresolvable differences alike — so a table whose plan was rejected can still show what drifted. It isNonewhen the read failed, because planning never ran.- resolution: delta_engine.application.relationships.TableResolution¶
- read: delta_engine.application.ports.ReadResult¶
- planning: delta_engine.application.planning.PlanningResult | None = None¶
- compiled: delta_engine.application.ports.CompiledPlan | None = None¶
- execution: delta_engine.application.ports.ExecutionResult | None = None¶
- blocked_failures: delta_engine.domain.collection_types.ListOrTuple[delta_engine.application.failures.ForeignKeyFailure] = ()¶
- property plan: delta_engine.domain.plan.ActionPlan | None¶
The accepted plan, or
Nonewhen reading or planning failed.
- property diff: delta_engine.domain.plan.TableDiff | None¶
The diff the planning outcome retains, or
Nonewhen the read failed.
- property failures: tuple[delta_engine.application.failures.Failure, Ellipsis]¶
Flatten canonical phase outcomes for callers.
Lifecycle order: structural, read, planning, execution — derived blocking sits at the execution position, where the run it replaced would have been.
- property desired: delta_engine.domain.model.DesiredTable¶
The declaration this run reconciled, as retained by its resolution.
- property qualified_name: delta_engine.domain.model.QualifiedName¶
The table identity from the declaration retained by this report.
- property status: TableRunStatus¶
Status of the earliest phase that failed; DEFERRED or SUCCESS when none did.
Failures dominate deferral: a deferred table that also failed resolution reports the failure, because that is what needs acting on.
- property has_failures: bool¶
True if the table did not fully succeed.
- property has_changes: bool¶
True when the plan holds actions — drift was found and validated.
- property creates_table: bool¶
True when the plan brings the table into existence rather than altering it.
- property statement_progress: StatementProgress | None¶
How far execution got, or
Nonewhen it did not run.
- to_dict() dict[str, Any]¶
Project this table’s run as plain, JSON-serialisable data.
The field names are a public stability contract (see the run report reference doc); changing them is a breaking change.
- class TableRunStatus¶
Bases:
enum.StrEnumHigh-level status of a table’s sync run.
- SUCCESS = 'SUCCESS'¶
- DEFERRED = 'DEFERRED'¶
- READ_FAILED = 'READ_FAILED'¶
- PLANNING_FAILED = 'PLANNING_FAILED'¶
- FOREIGN_KEY_FAILED = 'FOREIGN_KEY_FAILED'¶
- EXECUTION_FAILED = 'EXECUTION_FAILED'¶
- class ValidationFailure¶
Description of a validation rule failure.
subjectis what the failure is about — a column, property key, or aspect — used by the compact headline in the report grid. Rules that judge the table as a whole leave it empty.detailsare the individual differences behind a summary judgment, for a rule whose message names a whole aspect rather than one column. They are separate lines rather than newlines insidemessageso the report renderer owns their indentation, as it already does for the SQL line of an execution failure; a rule that embeds its own layout composes wrongly wherever the failure is nested.- phase: ClassVar[FailurePhase]¶
- rule_name: str¶
- message: str¶
- subject: str = ''¶
- details: delta_engine.domain.collection_types.ListOrTuple[str] = ()¶
- format_lines() tuple[str, Ellipsis]¶
- headline() str¶
- render_diff(report: delta_engine.application.report.SyncReport) str¶
Render every table’s planned changes as +/-/~ blocks, under a DIFF title.
- render_report(report: delta_engine.application.report.SyncReport) str¶
Render the run: title, optional dry-run banner, status grid, failures section, footer.