mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 16:32:00 +00:00
61 lines
3.0 KiB
Python
61 lines
3.0 KiB
Python
"""合并查询把输入查询的 SQL 检查结果传到指标上。
|
||
|
||
口径卡判「来源查询有没有 error 级问题」读的是来源快照上的 checks(data/sqlcheck.py 在数据源查询时写)。
|
||
合并查询在内存 SQLite 上执行,不对照数据目录检查,它的快照没有 checks——于是源库那条查询明明一对多关联后
|
||
重复计算了,经过一次合并,指标就看不出来了,照样完整出具。合并快照记着 inputs(每个输入的快照 id),
|
||
顺着它往下找才对得上。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import app.engine.nodes.metrics as metrics_mod
|
||
from app.engine.merge_query import MERGE_SOURCE
|
||
from app.engine.nodes.metrics import _error_checks
|
||
|
||
FANOUT = {"code": "fanout_sum", "level": "error", "message": "「订单」关联「订单明细」是一对多,求和会重复计算"}
|
||
NOTICE = {"code": "missing_valid_filter", "level": "warning", "message": "没有过滤作废记录"}
|
||
|
||
|
||
def _query(rows, checks=None):
|
||
snap = {"columns": ["日期", "门店", "销售额"], "rows": rows, "row_count": len(rows), "truncated": False}
|
||
return {**snap, "checks": checks} if checks else snap
|
||
|
||
|
||
def _merged(inputs):
|
||
return {"columns": ["日期", "门店", "销售额"], "rows": [["2026-05-01", "S01", 10]], "row_count": 1,
|
||
"truncated": False, "sql": "SELECT * FROM s JOIN v USING (日期, 门店)", "source": MERGE_SOURCE,
|
||
"inputs": [{"alias": a, "node_id": f"q_{a}", "artifact": art, "rows": 1} for a, art in inputs]}
|
||
|
||
|
||
def _store(monkeypatch, snapshots: dict):
|
||
monkeypatch.setattr(metrics_mod.artifact_store, "load", lambda artifact: snapshots.get(artifact))
|
||
|
||
|
||
def test_an_error_in_a_merge_input_reaches_the_metric(monkeypatch):
|
||
_store(monkeypatch, {
|
||
"sales": _query([["2026-05-01", "S01", 10]], [FANOUT, NOTICE]),
|
||
"visits": _query([["2026-05-01", "S01", 3]]),
|
||
"merged": _merged([("s", "sales"), ("v", "visits")]),
|
||
})
|
||
assert [c["code"] for c in _error_checks("merged")] == ["fanout_sum"]
|
||
|
||
|
||
def test_clean_inputs_leave_the_merge_clean(monkeypatch):
|
||
_store(monkeypatch, {"sales": _query([["2026-05-01", "S01", 10]], [NOTICE]),
|
||
"visits": _query([["2026-05-01", "S01", 3]]),
|
||
"merged": _merged([("s", "sales"), ("v", "visits")])})
|
||
assert _error_checks("merged") == []
|
||
|
||
|
||
def test_merges_of_merges_are_followed_and_cycles_do_not_hang(monkeypatch):
|
||
_store(monkeypatch, {
|
||
"sales": _query([["2026-05-01", "S01", 10]], [FANOUT]),
|
||
"inner": _merged([("s", "sales")]),
|
||
"outer": _merged([("m", "inner"), ("self", "outer")]), # 自引用:工件内容寻址做不出来,读坏的库也不能卡死
|
||
})
|
||
assert [c["code"] for c in _error_checks("outer")] == ["fanout_sum"]
|
||
|
||
|
||
def test_a_plain_query_snapshot_is_read_as_before(monkeypatch):
|
||
_store(monkeypatch, {"q": _query([["2026-05-01", "S01", 10]], [FANOUT, NOTICE])})
|
||
assert [c["code"] for c in _error_checks("q")] == ["fanout_sum"]
|