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
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.