Diffing¶
Compare two model versions to find additions, removals, and field-level changes.
diff_models()¶
diff_models() compares a baseline model against a revised model:
from etcion import diff_models
diff = diff_models(model_v1, model_v2)
print(diff.summary())
# "ModelDiff: 2 added, 1 removed, 3 modified"
By default, concepts are matched by id. Use match_by="type_name" to match by (type, name) tuple instead:
diff = diff_models(model_v1, model_v2, match_by="type_name")
ModelDiff¶
The returned ModelDiff is a frozen dataclass with three fields:
diff.added-- tuple of concepts present only in model_bdiff.removed-- tuple of concepts present only in model_adiff.modified-- tuple ofConceptChangefor concepts with field differences
for concept in diff.added:
print(f"+ {type(concept).__name__}: {concept.name}")
for concept in diff.removed:
print(f"- {type(concept).__name__}: {concept.name}")
ModelDiff is falsy when models are identical:
if not diff:
print("Models are identical")
ConceptChange and FieldChange¶
Each modified concept produces a ConceptChange containing a dict of FieldChange objects:
for change in diff.modified:
print(f"~ {change.concept_type} ({change.concept_id}):")
for field_name, fc in change.changes.items():
print(f" {field_name}: {fc.old!r} -> {fc.new!r}")
Serializing Diffs¶
Convert a diff to a JSON-compatible dict:
import json
print(json.dumps(diff.to_dict(), indent=2))
Or get a one-line summary:
print(diff.summary())
See also: examples/model_diff.py