refactor(harness): route workflow persistence through repositories
This commit is contained in:
+38
-20
@@ -42,12 +42,14 @@ def require_action(cfg, action: str) -> None:
|
||||
def promoted_tables_for(cfg, session_id: str | None) -> set[str] | None:
|
||||
if session_id is None:
|
||||
return None
|
||||
linking_path = cfg.paths.sessions / session_id / "schema_linking.json"
|
||||
if not linking_path.exists():
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit
|
||||
|
||||
raw = load_snapshot_or_exit(cfg, session_id).artifacts.get("schema_linking")
|
||||
if raw is None:
|
||||
return None
|
||||
from tht.session.models import SchemaLinking
|
||||
|
||||
linking = SchemaLinking.model_validate(json.loads(linking_path.read_text()))
|
||||
linking = SchemaLinking.model_validate(json.loads(raw))
|
||||
return {
|
||||
c.name for c in linking.candidates
|
||||
if c.kind == "table" and c.decision == "promoted"
|
||||
@@ -59,12 +61,14 @@ def promoted_tables_for(cfg, session_id: str | None) -> set[str] | None:
|
||||
def promoted_columns_for(cfg, session_id: str | None) -> set[str] | None:
|
||||
if session_id is None:
|
||||
return None
|
||||
linking_path = cfg.paths.sessions / session_id / "schema_linking.json"
|
||||
if not linking_path.exists():
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit
|
||||
|
||||
raw = load_snapshot_or_exit(cfg, session_id).artifacts.get("schema_linking")
|
||||
if raw is None:
|
||||
return None
|
||||
from tht.session.models import SchemaLinking
|
||||
|
||||
linking = SchemaLinking.model_validate(json.loads(linking_path.read_text()))
|
||||
linking = SchemaLinking.model_validate(json.loads(raw))
|
||||
return {
|
||||
c.name for c in linking.candidates
|
||||
if c.kind == "column" and c.decision == "promoted"
|
||||
@@ -182,7 +186,7 @@ def preview_cmd(
|
||||
"""Esecuzione controllata con LIMIT iniettato; aggregati mostrati per interi.
|
||||
|
||||
Se FILE è omesso e --session è fornito, il file viene risolto automaticamente
|
||||
come <workspace>/sessions/<session>/sql_final.sql (tramite _session_sql_file).
|
||||
dall'artefatto `sql_final` del repository della sessione.
|
||||
"""
|
||||
from tht.execute import ExecutionError
|
||||
|
||||
@@ -195,8 +199,7 @@ def preview_cmd(
|
||||
fg=typer.colors.RED, err=True,
|
||||
)
|
||||
raise typer.Exit(code=1)
|
||||
resolved = _session_sql_file(cfg, session)
|
||||
sql = resolved.read_text()
|
||||
sql = _session_sql(cfg, session)
|
||||
else:
|
||||
sql = _read_sql(file)
|
||||
check = validate_or_exit(cfg, sql, session)
|
||||
@@ -247,15 +250,32 @@ def preview_cmd(
|
||||
typer.secho(f" warning: {w}", fg=typer.colors.YELLOW)
|
||||
|
||||
|
||||
def _session_sql_file(cfg, session_id: str) -> Path:
|
||||
from tht.cli.session_cmd import load_session_or_exit, session_dir
|
||||
def _session_sql(cfg, session_id: str) -> str:
|
||||
from tht.cli.session_cmd import load_snapshot_or_exit
|
||||
|
||||
load_session_or_exit(cfg, session_id)
|
||||
sql_file = session_dir(cfg, session_id) / "sql_final.sql"
|
||||
if not sql_file.exists():
|
||||
typer.secho(f"ERRORE: {sql_file} non trovato.", fg=typer.colors.RED, err=True)
|
||||
sql = load_snapshot_or_exit(cfg, session_id).artifacts.get("sql_final")
|
||||
if sql is None:
|
||||
typer.secho("ERRORE: sql_final.sql non trovato.", fg=typer.colors.RED, err=True)
|
||||
raise typer.Exit(code=1)
|
||||
return sql_file
|
||||
return sql
|
||||
|
||||
|
||||
@sql_app.command("set-final")
|
||||
def set_final_cmd(
|
||||
session: str = typer.Option(..., "--session"),
|
||||
file: str = typer.Option(..., "--file", help="File SQL, oppure '-' per stdin."),
|
||||
config: Path = CONFIG_OPT,
|
||||
) -> None:
|
||||
"""Persist clean final SQL through the configured session repository."""
|
||||
import sys
|
||||
|
||||
from tht.cli.session_cmd import load_session_or_exit, session_repository
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
load_session_or_exit(cfg, session)
|
||||
sql = sys.stdin.read() if file == "-" else _read_sql(Path(file))
|
||||
session_repository(cfg).write_artifact(session, "sql_final", sql)
|
||||
typer.secho("OK: SQL finale salvato.", fg=typer.colors.GREEN)
|
||||
|
||||
|
||||
@sql_app.command("save")
|
||||
@@ -266,9 +286,8 @@ def save_cmd(
|
||||
) -> None:
|
||||
"""Salva una copia di sql_final.sql nel percorso indicato (su richiesta esplicita)."""
|
||||
cfg = _load_config_or_exit(config)
|
||||
sql_file = _session_sql_file(cfg, session)
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
dest.write_text(sql_file.read_text())
|
||||
dest.write_text(_session_sql(cfg, session))
|
||||
typer.secho(f"OK: SQL salvato in {dest}", fg=typer.colors.GREEN)
|
||||
|
||||
|
||||
@@ -286,8 +305,7 @@ def export_cmd(
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
require_action(cfg, "export")
|
||||
sql_file = _session_sql_file(cfg, session)
|
||||
sql = sql_file.read_text()
|
||||
sql = _session_sql(cfg, session)
|
||||
validate_or_exit(cfg, sql, session)
|
||||
try:
|
||||
result = do_run(cfg, sql, limit=cfg.execution.max_export_rows)
|
||||
|
||||
Reference in New Issue
Block a user