diff --git a/backend/app/data/catalog.py b/backend/app/data/catalog.py index f4431d7d..25fae279 100644 --- a/backend/app/data/catalog.py +++ b/backend/app/data/catalog.py @@ -1613,12 +1613,16 @@ def query_snapshot_meta(source: Any, sql: str) -> dict[str, Any]: """查询快照工件引用的 meta:源 id、源名、SQL 里的表名。数据源查询工具存快照时写进去,table_usage 据此计数。 表名的取法和证据台账一样(evidence.sql_tables:FROM / JOIN 后面的表,去掉注释和字符串)。meta 只在 - 工件引用表里,不进工件内容:查询快照的内容哈希不变。 + 工件引用表里,不进工件内容:查询快照的内容哈希不变。不抛异常:它和查询快照在同一个 try 里, + 这里出错会让快照存不下,证据就断了。 """ from app.engine.evidence import sql_tables - return {"source_id": getattr(source, "id", None), "source": getattr(source, "name", None), - "tables": sql_tables(sql or "")} + try: + tables = sql_tables(sql or "") + except Exception: # noqa: BLE001 - 解析不了就当没用到表,只影响使用次数 + tables = [] + return {"source_id": getattr(source, "id", None), "source": getattr(source, "name", None), "tables": tables} async def table_usage(session: AsyncSession, source: Any) -> dict[str, int]: diff --git a/backend/app/tools/datasource.py b/backend/app/tools/datasource.py index bd2350a7..b7c5da17 100644 --- a/backend/app/tools/datasource.py +++ b/backend/app/tools/datasource.py @@ -222,7 +222,7 @@ async def build_datasource_tools( except table_versions.SnapshotMissing as e: tools.extend(_unavailable_tool(row, prefix, str(e)) for prefix in prefixes) continue - entries = await _catalog_of(session, row) + entries = await _catalog_of(row) for prefix in prefixes: if prefix == QUERY_PREFIX: tools.append(_make_query_tool(source, ctx, fixed=fixed, catalog=entries)) @@ -231,13 +231,17 @@ async def build_datasource_tools( return tools -async def _catalog_of(session: AsyncSession, row: DataSource) -> dict[str, data_catalog.CatalogEntry]: +async def _catalog_of(row: DataSource) -> dict[str, data_catalog.CatalogEntry]: """这个源的数据目录,建工具时读一次:db_schema 给模型看的和查询时冻结进表结构快照的是同一版。 - 读不到(库还没建这张表之类)就当没有目录,工具照常可用——目录是附加说明,不能挡住查询。 + 读不到就当没有目录,工具照常可用——目录是附加说明,不能挡住查询。用单独的会话读:出错要回滚, + 而回滚会让调用方会话里已经加载的对象(row)全部过期,之后再读属性就是异步环境里的懒加载。 """ + from app.db.base import SessionLocal + try: - return await data_catalog.read_catalog(session, row.id) + async with SessionLocal() as own: + return await data_catalog.read_catalog(own, row.id) except Exception: # noqa: BLE001 logger.exception("读取数据源 %s 的数据目录失败,本次不附目录", row.name) return {}