chore: auto-commit (43 archivos)
- .mcp.json - bash/functions/infra/write_mcp_jupyter_config.md - bash/functions/infra/write_mcp_jupyter_config.sh - cpp/CMakeLists.txt - cpp/apps/chart_demo - cpp/apps/shaders_lab - cpp/functions/gfx/gl_framebuffer.cpp - cpp/functions/gfx/gl_framebuffer.h - cpp/functions/gfx/gl_framebuffer.md - cpp/functions/gfx/mesh_gpu.md - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
---
|
||||
name: clickhouse_query
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def clickhouse_query(base_url: str, sql: str, *, user: str = 'default', password: str = '', database: str = 'analytics', timeout: float = 30.0) -> list[dict]"
|
||||
description: "Ejecuta un SQL contra ClickHouse via HTTP (puerto 8123) y retorna los resultados como lista de dicts. Para SELECT usa JSONEachRow automaticamente; para DDL/DML retorna []."
|
||||
tags: [clickhouse, analytics, http, query, select, read]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: [json, urllib.request, urllib.parse, urllib.error]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/infra/clickhouse_query.py"
|
||||
params:
|
||||
- name: base_url
|
||||
desc: "URL base del servidor ClickHouse sin trailing slash. Ej: 'http://127.0.0.1:18123'. Para tunel SSH, apunta al puerto local reenviado."
|
||||
- name: sql
|
||||
desc: "SQL completo a ejecutar. El caller escribe el SQL entero; esta funcion no anade nada. Para SELECT retorna filas; para CREATE/INSERT/etc. retorna []."
|
||||
- name: user
|
||||
desc: "Usuario ClickHouse para autenticacion via header X-ClickHouse-User (default: 'default')."
|
||||
- name: password
|
||||
desc: "Contrasena ClickHouse para autenticacion via header X-ClickHouse-Key (default: cadena vacia)."
|
||||
- name: database
|
||||
desc: "Base de datos ClickHouse enviada como parametro de query (default: 'analytics')."
|
||||
- name: timeout
|
||||
desc: "Timeout de socket en segundos (default: 30.0)."
|
||||
output: "Lista de dicts, uno por fila del resultado. Lista vacia para sentencias sin resultado (DDL, INSERT). Los numeros Int64 de ClickHouse llegan como strings JSON — castear con int() si se necesita aritmetica."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from infra import clickhouse_query
|
||||
|
||||
# Contar filas
|
||||
rows = clickhouse_query(
|
||||
"http://127.0.0.1:18123",
|
||||
"SELECT count() AS c FROM analytics.gnula_movies",
|
||||
user="analytics",
|
||||
password="secret",
|
||||
database="analytics",
|
||||
)
|
||||
print(int(rows[0]["c"])) # Int64 llega como string → castear
|
||||
|
||||
# Leer ultimas inserciones
|
||||
recent = clickhouse_query(
|
||||
"http://127.0.0.1:18123",
|
||||
"SELECT snapshot_ts, title, status FROM analytics.gnula_movies ORDER BY snapshot_ts DESC LIMIT 5",
|
||||
user="analytics",
|
||||
password="secret",
|
||||
)
|
||||
for r in recent:
|
||||
print(r["snapshot_ts"], r["title"], r["status"])
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Leer agregados, validar ingest o inspeccionar datos en ClickHouse via HTTP sin dependencias externas. Util en ETLs de validacion, notebooks, scripts de monitoreo y pipelines que ya usan `clickhouse_insert_rows_py_infra` para escribir y necesitan verificar el resultado. Tambien sirve para ejecutar DDL (CREATE TABLE, etc.) cuando la respuesta vacia es esperada.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- `base_url` sin trailing slash: `"http://127.0.0.1:18123"`, no `"http://127.0.0.1:18123/"`.
|
||||
- El caller escribe el SQL completo. Esta funcion no anade FORMAT, LIMIT ni nada — lo que se pasa es lo que se ejecuta.
|
||||
- **Int64 y UInt64 de ClickHouse llegan como strings JSON** en JSONEachRow. Castear explicitamente: `int(row["c"])`. Float64 llega como numero JSON nativo.
|
||||
- Para SELECT sin FORMAT explicito, `default_format=JSONEachRow` se aplica automaticamente via query param. No hace falta escribir `FORMAT JSONEachRow` en el SQL.
|
||||
- DDL y DML (CREATE, INSERT, ALTER) retornan cuerpo vacio → la funcion retorna `[]`. No es un error.
|
||||
- Para tunel SSH: `ssh -L 18123:localhost:8123 user@host` y usar `base_url="http://127.0.0.1:18123"`.
|
||||
- En caso de error HTTP, `ValueError` incluye el codigo y los primeros 500 caracteres del cuerpo — util para depurar errores de SQL o permisos.
|
||||
- Queries con resultado muy grande se leen enteras en memoria. Para resultados masivos, usar LIMIT o streaming manual con `urllib.request.urlopen` directamente.
|
||||
Reference in New Issue
Block a user