refactor composer to use sqlalchemy, avoid string concatenations and follow conventions

This commit is contained in:
2026-06-03 12:10:30 -03:00
parent cbc7df8c60
commit be09fcde2c
16 changed files with 546 additions and 273 deletions

View File

@@ -151,6 +151,12 @@ class Recon:
metrics: dict[str, Metric]
column_to_tables: dict[str, list[str]] = field(default_factory=dict)
relationships: list[Relationship] = field(default_factory=list)
# Storage-encoding overrides keyed by Column.semantic_type. Each value is a
# map of role → SQL template with a `{col}` placeholder (e.g.
# {"date_yymmdd": {"as_date": "TO_DATE(LPAD({col}::text, 6, '0'), 'YYMMDD')"}}).
# The composer merges these over its DEFAULT_ENCODINGS — the dataset wins.
# Empty for datasets whose columns are stored in native types.
encodings: dict[str, dict[str, str]] = field(default_factory=dict)
# ── Read-side helpers used by Analyses + the composer ──
@@ -299,6 +305,7 @@ class Recon:
"metrics": {n: m.to_dict() for n, m in self.metrics.items()},
"column_to_tables": self.column_to_tables,
"relationships": [r.to_dict() for r in self.relationships],
"encodings": self.encodings,
}
@classmethod
@@ -309,4 +316,5 @@ class Recon:
metrics={n: Metric.from_dict(m) for n, m in d.get("metrics", {}).items()},
column_to_tables=d.get("column_to_tables", {}),
relationships=[Relationship(**r) for r in d.get("relationships", [])],
encodings=d.get("encodings", {}) or {},
)