927437a8d8
Sistema FleetView para centralizar la flota de procesos Claude Code vivos en una sola ventana kitty + tmux (socket aislado -L fleet) con un panel TUI: - list_claude_fleet (+ tipo claude_fleet): escanea ~/.claude/sessions + goals + runtime, valida procesos vivos (anti-PID-reciclado), join por sessionId. - list_resumable_claudes (+ tipo resumable_claude): sesiones cerradas reanudables. - wrappers tmux: tmux_new_claude_window (con --resume), tmux_swap_window_into_console (preserva ancho del sidebar), tmux_map_claude_panes. - launch_kittyclaude: comando entrypoint; instala atajos alt+flechas/enter/n/0/k/r, mouse on, remain-on-exit off; fija el ancho del sidebar con hooks. - docs/capabilities/claude-fleet.md + entrada en el INDEX. Incluye ademas funciones datascience en progreso (excel/duckdb/postgres) y ajustes varios de docs e infra de otra sesion, agrupados aqui para no perderlos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.7 KiB
4.7 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| pg_query | function | py | infra | 1.0.0 | impure | def pg_query(dsn: str, sql: str, params: list = None, max_rows: int = 10000) -> dict | Ejecuta un SELECT contra PostgreSQL via psycopg2 y devuelve las filas como list[dict] sin lanzar. Abre la conexion con el DSN, marca la transaccion read-only (SET TRANSACTION READ ONLY) y usa RealDictCursor para que cada fila sea un dict columna->valor. Devuelve {status:'ok', columns, rows, row_count, truncated} en exito y {status:'error', error} en fallo (estilo duckdb_query_readonly). Usa parametros posicionales con el marcador %s. Trunca a max_rows para proteger memoria. Normaliza valores no JSON-serializables: date/datetime/time a isoformat(), Decimal a float, bytes/memoryview a base64, UUID a str. Cierra la conexion siempre en try/finally. Espejo de duckdb_query_readonly para Postgres. Depende de psycopg2 (2.9.x en python/.venv). |
|
false | error_py_core |
|
|
dict. En exito: {status:'ok', columns:[str,...], rows:[{col:val,...},...], row_count:int, truncated:bool}; las filas son dicts (RealDictCursor). En error (sin lanzar): {status:'error', error:str}. Los valores estan normalizados a tipos JSON-serializables. | true |
|
python/functions/infra/pg_query_test.py | python/functions/infra/pg_query.py |
Ejemplo
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from infra.pg_query import pg_query
dsn = "postgresql://user:pass@localhost:5433/trends"
# SELECT con parametro posicional (nunca interpolar el valor en el SQL).
res = pg_query(
dsn,
"SELECT product, price FROM prices WHERE source = %s ORDER BY price DESC",
params=["amazon"],
max_rows=100,
)
print(res["status"]) # ok
print(res["columns"]) # ['product', 'price']
print(res["rows"][0]) # {'product': 'Widget X', 'price': 19.99}
print(res["truncated"]) # False
Cuando usarla
Usala cuando necesites leer datos de Postgres y pasarlos a otro paso de una
composicion como dict serializable: inspeccionar una tabla, validar el resultado de
un pipeline de ingesta, alimentar un dashboard o report, o consultar tablas
materializadas. Es el espejo de duckdb_query_readonly para Postgres. Para escribir
usa pg_insert_rows, pg_upsert o pg_apply_sql.
Gotchas
- Lectura real contra un servidor (impura). La transaccion se marca read-only con
set_session(readonly=True)y nunca se hace commit (rollback al final): cualquierINSERT/UPDATE/DELETEen el SQL falla a nivel de servidor y vuelve como{status:'error', ...}. NO es un sandbox de filesystem — read-only protege la base, no impide leer datos sensibles si el SQL viene de un cliente no confiable. - Inyeccion SQL: los valores van siempre por
paramscon el marcador%s, nunca interpolados en el string del SQL. Esta funcion NO valida ni parametriza identificadores (nombres de tabla/columna): si necesitas un nombre de tabla dinamico, validalo tu antes con^[A-Za-z_][A-Za-z0-9_]*$. max_rowsprotege la memoria: una query que devuelve millones de filas se trunca amax_rowsy marcatruncated=True. Para todas las filas, pagina con LIMIT/OFFSET o subemax_rowsconscientemente.- Valores no JSON-serializables se normalizan en la salida: date/datetime/time a
isoformat(), Decimal a float (posible perdida de precision frente al decimal exacto), bytes/memoryview a base64 y UUID a str. - Conexion nueva por llamada (sin pool). Para muchas consultas pequenas en bucle, reusa una conexion fuera de esta funcion o agrupa el trabajo en una sola query.
- Nunca lanza: DSN invalido, servidor caido, SQL malformado o falta de psycopg2
vuelven como
{status:'error', error:str}.