"""NL2SQL 运维任务执行历史适配器。""" from __future__ import annotations import json from datetime import datetime from sqlalchemy import text from nl2sql.audit import _sanitize async def record_job_history(db, result, *, elapsed_ms: float, parameter_summary: dict | None = None) -> None: """保存任务结果摘要,不保存原始参数和连接凭据。""" statement = text( """ INSERT INTO nl2sql_job_history (job_name, status, attempts, detail, error_type, parameter_summary, elapsed_ms, create_time) VALUES (:job_name, :status, :attempts, :detail, :error_type, :parameter_summary, :elapsed_ms, :create_time) """ ) await db.execute( statement, { "job_name": result.name, "status": result.status, "attempts": result.attempts, "detail": json.dumps(_sanitize(result.detail or {}), ensure_ascii=False), "error_type": result.error_type, "parameter_summary": json.dumps(_sanitize(parameter_summary or {}), ensure_ascii=False), "elapsed_ms": elapsed_ms, "create_time": datetime.now(), }, ) await db.commit() async def record_job_history_safely(db, result, *, elapsed_ms: float, parameter_summary: dict | None = None) -> bool: """任务历史写入失败时降级,不影响任务结果返回。""" try: await record_job_history( db, result, elapsed_ms=elapsed_ms, parameter_summary=parameter_summary, ) except Exception: # noqa: BLE001 历史故障不能阻断运维任务 return False return True async def list_job_history(db, *, page: int = 1, page_size: int = 20, status: str | None = None) -> list[dict]: """分页查询任务历史,只返回执行摘要,不返回 detail 明细。""" conditions = "WHERE (:status IS NULL OR status = :status)" statement = text( f""" SELECT id, job_name, status, attempts, error_type, elapsed_ms, create_time FROM nl2sql_job_history {conditions} ORDER BY id DESC LIMIT :limit OFFSET :offset """ ) result = await db.execute( statement, { "status": status, "limit": max(1, min(page_size, 100)), "offset": max(0, (page - 1) * page_size), }, ) return [dict(row) for row in result.mappings().all()]