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,80 @@
|
||||
---
|
||||
name: clickhouse_insert_rows
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def clickhouse_insert_rows(base_url: str, table: str, rows: list[dict], *, user: str = 'default', password: str = '', database: str = 'analytics', timeout: float = 30.0) -> int"
|
||||
description: "Inserta una lista de dicts en ClickHouse via HTTP (puerto 8123) usando el formato JSONEachRow. Retorna el numero de filas enviadas."
|
||||
tags: [clickhouse, analytics, http, insert, ingest, etl]
|
||||
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_insert_rows.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: table
|
||||
desc: "Nombre de la tabla destino, con o sin prefijo de base de datos. Ej: 'analytics.gnula_movies' o 'gnula_movies'."
|
||||
- name: rows
|
||||
desc: "Lista de dicts a insertar. Cada dict se serializa como una linea JSON. Las claves deben coincidir con columnas existentes; columnas ausentes usan DEFAULT."
|
||||
- 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: "Entero con el numero de filas insertadas (len(rows)). Retorna 0 si rows esta vacio sin contactar el servidor."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from infra import clickhouse_insert_rows
|
||||
|
||||
n = clickhouse_insert_rows(
|
||||
"http://127.0.0.1:18123",
|
||||
"analytics.gnula_movies",
|
||||
[
|
||||
{
|
||||
"snapshot_ts": "2026-05-30 14:00:00",
|
||||
"href": "/pelicula/avatar-el-camino-del-agua",
|
||||
"title": "Avatar: El camino del agua",
|
||||
"year": 2022,
|
||||
"flags": "es.png",
|
||||
"lang_es": 1,
|
||||
"status": "pending",
|
||||
"in_library": 0,
|
||||
"detected_at": "2026-05-30T14:00:00",
|
||||
"downloaded_at": "",
|
||||
}
|
||||
],
|
||||
user="analytics",
|
||||
password="secret",
|
||||
database="analytics",
|
||||
)
|
||||
print(f"Inserted {n} rows")
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando un ETL empuja snapshots o eventos a ClickHouse via HTTP (puerto 8123), incluyendo a traves de un tunel SSH a un ClickHouse interno no expuesto publicamente. Alternativa ligera (solo stdlib) a `clickhouse-driver` o `clickhouse-connect` cuando no se quieren dependencias externas.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- `base_url` sin trailing slash: `"http://127.0.0.1:18123"`, no `"http://127.0.0.1:18123/"`.
|
||||
- Fechas y datetimes deben pasarse como strings en formato que ClickHouse acepte (`"YYYY-MM-DD HH:MM:SS"`) o como enteros epoch. El caller formatea; esta funcion no convierte tipos.
|
||||
- Arrays van como listas JSON nativas Python: `{"tags": ["drama", "sci-fi"]}`.
|
||||
- Columnas ausentes en un dict usan el valor DEFAULT de la tabla (JSONEachRow ignora claves faltantes). No falla.
|
||||
- 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 schema o SQL malformado.
|
||||
- Lotes grandes: no hay batching interno. Si `rows` tiene miles de elementos, el body puede ser grande. Partir en chunks desde el caller si es necesario.
|
||||
Reference in New Issue
Block a user