Skip to main content

Module diff

Module diff 

Source
Expand description

Schema diff engine: given a target SchemaDescriptor and the live database state (introspected via pg_catalog), produce ordered DDL SQL statements to bring the database in sync with the target.

Used by pylon migration watch (apply directly) and pylon migration create (render as a migration file body). Pure computation — no I/O.

Structs§

ColRenameCandidate
A detected potential column rename within an existing table: a dropped column and an added column with the same Postgres type.
DbCheck
DbColumn
DbComposite
A composite type as the database has it. attributes is in attribute order, which is part of the type’s identity: a tuple’s members are read by position, so two types with the same attributes in a different order are not the same type.
DbCompositeAttr
DbDomain
DbEnum
DbForeignKey
DbFunction
DbIndex
DbSequence
DbState
Snapshot of the live PostgreSQL database, built by Python from pg_catalog queries.
DbTable
DbView
DiffOp
A single DDL operation produced by the diff engine.
FillRequired
A column that is being made NOT NULL but currently contains (or could contain) NULL rows, requiring a fill expression to backfill existing rows before the constraint can be added.
Guidance
Guidance for re-diffing after a rejected rename candidate — mirrors the two ambiguity detectors below; a plain create/alter/drop has no alternative reading to search for, so rejecting one of those just excludes it (handled by the interactive caller, not here).
MigrationStep
RequiredInput
One \(placeholder) token embedded in a step’s DDL that the caller must resolve to a PyQL expression (compiled via query::compile_fill_expr, evaluated against type_name) before executing that statement — mirrors how a fill expression is resolved, just for a type-change’s conversion expression instead of a backfill.
TypeRenameCandidate
A detected potential type (table) rename: a dropped table whose column structure closely matches a newly-created type.

Enums§

OpKey
Stable identity an emitted step is grouped by. Every DDL statement that answers the same logical question (e.g. every column/FK/trigger change to one table) shares one key and therefore one step.
Verb

Functions§

db_state_from_json
Deserialize a DbState from the JSON stored in _pylon."Migrations".db_state.
db_state_to_json
Serialize a DbState to a JSON string for storage in _pylon."Migrations".db_state.
detect_col_renames
Detect potential column renames within tables that exist in both current and target. A candidate is a (dropped_col, added_col) pair in the same table with the same Postgres type. Candidates already rejected once (guidance.banned_col_renames) are never proposed again.
detect_fill_required
Detect all properties that are being made NOT NULL but whose existing rows may contain NULL values and therefore require a fill expression.
detect_type_renames
Detect potential type (table) renames: tables that exist in current but not in target, paired with types that exist in target but not in current, where the column-set Jaccard similarity meets a threshold. Candidates already rejected once (guidance.banned_type_renames) are never proposed again — a re-diff after “no” should offer something else.
diff_schema
Compute ordered DDL SQL strings to bring a database in sync with target. All statements use plain (non-CONCURRENTLY) index creation — suitable for watch mode where everything runs inside a single transaction.
diff_schema_ops
Compute ordered DiffOps suitable for a migration file body. Index creation on pre-existing tables uses CONCURRENTLY and is marked non_transactional = true so create can insert step-boundary markers.
diff_schema_ops_with_renames_and_fills
Full diff with confirmed renames and fill expressions applied.
diff_schema_steps
Compute the diff as one MigrationStep per logical schema-level question — for an interactive caller that confirms/rejects one object at a time instead of a flat DDL dump. fill_index marks columns whose NOT NULL constraint is deferred to a caller-supplied backfill (see diff_schema_ops_with_renames_and_fills’s doc comment).
diff_schema_steps_with_renames_and_fills
Like diff_schema_ops_with_renames_and_fills but returns MigrationSteps grouped by object instead of a flat DiffOp list — for the interactive confirmation loop. Renames themselves aren’t represented as steps here; the caller resolves those first (see detect_type_renames/ detect_col_renames + Guidance) and passes the confirmed set in, same as the flat-DiffOp version. A fill’s UPDATE + SET NOT NULL folds into its own table’s step (falling back to a standalone step in the rare case that table has no other change in this diff).
diff_states
Diff two live-database snapshots (used by squash to capture the net effect of a range of migrations applied to an ephemeral shadow database). “before” = state at the start of the squashed range, “after” = state at the end. Returns DiffOps suitable for a migration file body.
expected_triggers
missing_extension_ddl
CREATE EXTENSION IF NOT EXISTS statements for every extension target requires that isn’t already present in current — meant to be prepended to an assembled migration/watch sync unconditionally, outside the interactive per-step confirmation flow: enabling a required extension isn’t a design decision to confirm or reject, it’s a hard prerequisite the rest of the DDL can’t succeed without.
required_extensions
Postgres extensions target needs in order for its own DDL to apply cleanly — currently just vector (pgvector), needed the moment any type declares a vector index. Extending this to a future extension-dependent feature is just adding another check here; the caller-facing surface (missing_extension_ddl) doesn’t change.
schema_content_changed
True when target differs from previous in ANY way at all — not just the DDL-visible parts diff_schema_steps/diff_schema_ops can see.
schema_to_db_state
Convert a compiled SchemaDescriptor into the equivalent DbState snapshot.