recon-driven sql composer; pick → compose → execute; llm out of structural sql

This commit is contained in:
2026-06-03 11:01:02 -03:00
parent 61494362a3
commit 29c620b2c2
27 changed files with 1516 additions and 249 deletions

View File

@@ -80,16 +80,25 @@ def _read_yaml(path: Path) -> dict[str, Any]:
return yaml.safe_load(path.read_text()) or {}
def _parse_column_descs(raw: dict[str, Any]) -> dict[str, str]:
"""Accept either the flat form `{table.col: desc}` or the nested form
`{table: {col: desc}}`. Returns flat form."""
out: dict[str, str] = {}
for k, v in raw.items():
def _parse_column_specs(raw: dict[str, Any]) -> dict[str, dict[str, Any]]:
"""Accept either the flat form `{table.col: <spec>}` or the nested form
`{table: {col: <spec>}}`. Each `<spec>` is either a bare description
string OR a dict `{desc?: str, type?: str}` where `type` is a domain-
level semantic type (e.g. "date_yymmdd"). Returns flat form: each value
is normalised to `{desc, type}`."""
def norm(v: Any) -> dict[str, Any]:
if isinstance(v, dict):
for col, desc in v.items():
out[f"{k}.{col}"] = desc
return {"desc": v.get("desc") or v.get("description"), "type": v.get("type")}
return {"desc": v, "type": None}
out: dict[str, dict[str, Any]] = {}
for k, v in raw.items():
if isinstance(v, dict) and not ("desc" in v or "description" in v or "type" in v):
# Nested: {table: {col: spec}}.
for col, sub in v.items():
out[f"{k}.{col}"] = norm(sub)
else:
out[k] = v
out[k] = norm(v)
return out
@@ -101,19 +110,20 @@ def merge_into_recon(dataset: str, extracted: dict[str, Any]) -> Recon:
metrics_yaml = _read_yaml(DATASETS_DIR / dataset / "metrics.yaml")
table_descs: dict[str, str] = aug.get("tables", {}) or {}
col_descs = _parse_column_descs(aug.get("columns", {}) or {})
col_specs = _parse_column_specs(aug.get("columns", {}) or {})
tables: dict[str, Table] = {}
for tname, t_data in extracted["tables"].items():
cols = [
Column(
cols = []
for c in t_data["columns"]:
spec = col_specs.get(f"{tname}.{c['name']}", {})
cols.append(Column(
name=c["name"],
sql_type=c["sql_type"],
nullable=c["nullable"],
description=col_descs.get(f"{tname}.{c['name']}"),
)
for c in t_data["columns"]
]
description=spec.get("desc"),
semantic_type=spec.get("type"),
))
tables[tname] = Table(
name=tname,
description=table_descs.get(tname),