"""N+1 쿼리 회귀 — 트리/대시보드의 실제 발행 쿼리 수를 센다.""" from contextlib import contextmanager from sqlalchemy import event @contextmanager def count_queries(engine): counter = {"n": 0} def _before(conn, cursor, statement, *a, **k): counter["n"] += 1 event.listen(engine, "before_cursor_execute", _before) try: yield counter finally: event.remove(engine, "before_cursor_execute", _before) def test_tree_no_nplus1(client, session): _s, engine = session with count_queries(engine) as c: r = client.get("/api/tree") assert r.status_code == 200 assert c["n"] <= 6, f"트리 쿼리 {c['n']}개 — N+1 의심" def test_dashboard_query_budget(client, session): _s, engine = session with count_queries(engine) as c: r = client.get("/api/dashboard") assert r.status_code == 200 assert c["n"] <= 12, f"대시보드 쿼리 {c['n']}개 — 집계 합치기 필요"