SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%

ch: only a trailing FORMAT clause disables the JSONEachRow default

Simon-Pierre Boucher committed 12 days ago (Sep 12, 2026) parent e36455e

1 changed file +7 −2

modified apps/api/src/internetpressure/db/ch.py +7 −2
@@ -8,6 +8,7 @@ Usage:
8 8 from __future__ import annotations
9 9
10 10 import logging
11 +import re
11 12 from pathlib import Path
12 13 from typing import Any
13 14
@@ -63,12 +64,16 @@ async def raw(sql: str, *, database: str | None = None, body: bytes | None = Non
63 64
64 65
65 66 async def query(sql: str, params: dict | None = None) -> list[dict[str, Any]]:
66 − if "FORMAT" not in sql.upper():
67 + # only a trailing "FORMAT <name>" counts (an id like "plateforme" inside an IN (...) list must not match)
68 + if not re.search(r"\bFORMAT\s+\w+\s*;?\s*$", sql, re.IGNORECASE):
67 69 sql = sql.rstrip().rstrip(";") + " FORMAT JSONEachRow"
68 70 out = await raw(sql, params=params)
69 71 if not out.strip():
70 72 return []
71 − return [loads(line) for line in out.splitlines() if line.strip()]
73 + try:
74 + return [loads(line) for line in out.splitlines() if line.strip()]
75 + except Exception as exc: # noqa: BLE001 — ClickHouse can emit an exception text after a 200 header was sent
76 + raise CHError(f"ClickHouse returned non-JSON rows ({exc}): {out[:400]!r}\n-- {sql[:300]}") from exc
72 77
73 78
74 79 async def query_one(sql: str, params: dict | None = None) -> dict[str, Any] | None:
75 80