# -*- coding: utf-8 -*- """A3 自测:直接调 build_slice(不启服务),校验真实库切片与空态。""" import os, sys, json sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) for line in open('/root/cma-management/backend/.env'): line = line.strip() if '=' in line and not line.startswith('#') and line.split('=')[0].startswith(('CMA_DB', 'ERP_DB')): k, v = line.split('=', 1); os.environ.setdefault(k, v) from app.database import get_session_local from app.api.map_dimensions import build_slice, _time_options, _store_options, _product_options db = get_session_local()() def brief(r): print("slice:", r["slice"], "| empty:", r["empty"], "|", r["empty_reason"]) for o in r["objectives"]: ks = [f'{k["kpi_code"]}={k["actual_value"]}/{k["target_value"]}@{k["achievement_pct"]}%({k["level"]},{k["aggregation"]}){"" if k["available"] else "[空:"+str(k["reason"])[:36]+"]"}' for k in o["kpis"]] if ks: print(" ", o["dimension_key"], o["name"], "|", "; ".join(ks)) print("=== 1) 2026-08 月切片 (map 65)") brief(build_slice(db, 1, 65, "2026-08", None, None)) print("\n=== 2) 2026-Q3 季切片") brief(build_slice(db, 1, 65, "2026-Q3", None, None)) print("\n=== 3) 2026 年切片") brief(build_slice(db, 1, 65, "2026", None, None)) print("\n=== 4) 产品切片 酣客酱酒 @2026-08") brief(build_slice(db, 1, 65, "2026-08", None, "酣客酱酒")) print("\n=== 5) 产品切片 不存在产品 @2026-08") brief(build_slice(db, 1, 65, "2026-08", None, "不存在的产品X")) print("\n=== 6) 门店切片 一店 @2026-08") brief(build_slice(db, 1, 65, "2026-08", "一店", None)) print("\n=== 7) entity 隔离: map65 + entity2") try: build_slice(db, 2, 65, "2026-08", None, None) print("FAIL 未拦截") except Exception as e: print("OK 拦截:", type(e).__name__, getattr(e, "status_code", ""), getattr(e, "detail", e)) print("\n=== 8) options map65") o = build_slice(db, 1, 65, None, None, None) print("time dims:", json.dumps(o["dims"]["time"], ensure_ascii=False)[:300]) print("store:", json.dumps(o["dims"]["store"], ensure_ascii=False)[:300]) print("product:", json.dumps(o["dims"]["product"], ensure_ascii=False)[:300]) db.close()