Files
fn_registry/python/functions/pipelines/run_mssql_query.md
T
egutierrez 86d68dc9f0 feat(infra): conexion y consulta directa a SQL Server (Navision) via pymssql
Grupo de capacidad nuevo 'sql-connect' (3 funciones) para conectar a un
Microsoft SQL Server (donde corre Navision) y consultar directamente, en
lugar del ida y vuelta manual de pegar CSVs.

- mssql_connect_py_infra: abre conexion pymssql (login_timeout acotado,
  credenciales por argumento, RuntimeError claro si falla).
- mssql_query_py_infra: SELECT parametrizada con binding seguro (sin
  inyeccion) sobre conexion abierta; devuelve {columns, rows, row_count};
  0 filas -> lista vacia; max_rows con fetchmany; read-only.
- run_mssql_query_py_pipelines: one-shot que compone connect+query y cierra
  siempre; CLI imprime JSON o CSV; contrasena desde env var (pass).

Pagina madre docs/capabilities/sql-connect.md + fila en INDEX.md.
Dependencia pymssql>=2.3.13 anadida a python/pyproject.toml + uv.lock.
Tests mock-based (11) verdes; error path verificado end-to-end contra el
driver real (host inalcanzable -> RuntimeError, acotado por login_timeout).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 11:29:49 +02:00

5.2 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
run_mssql_query pipeline py pipelines 1.0.0 impure def run_mssql_query(host: str, database: str, user: str, password: str, sql: str, params=None, port: int = 1433, max_rows: int | None = None, login_timeout: int = 15, query_timeout: int = 30) -> dict One-shot contra SQL Server (Navision): abre conexion, ejecuta UNA SELECT parametrizada y cierra, devolviendo {columns, rows, row_count}. Compone mssql_connect + mssql_query. Pensado para iterar queries de Navision en un solo comando (fn run run_mssql_query ...) en vez del copia-pega manual. CLI imprime JSON o CSV; la contrasena se lee de una env var (recomendado: MSSQL_PASSWORD=$(pass navision/password)), nunca hardcodeada.
mssql
sqlserver
navision
sql-connect
pipelines
mssql_connect_py_infra
mssql_query_py_infra
false error_go_core
name desc
host Host o IP del SQL Server. Desde WSL2 debe ser la IP LAN de Windows, no localhost.
name desc
database Nombre de la base de datos a la que conectar (p.ej. la BD de Navision).
name desc
user Usuario de login de SQL Server.
name desc
password Contrasena del usuario. Se pasa desde pass/env, nunca como literal en codigo.
name desc
sql Sentencia SELECT con placeholders pymssql %s (posicional) o %(nombre)s (nombrado) para los valores.
name desc
params Tuple/list (posicional), dict (nombrado) o None. Binding seguro del driver (sin inyeccion).
name desc
port Puerto TCP del SQL Server. Default 1433.
name desc
max_rows Si es int positivo, devuelve solo las primeras max_rows filas; None devuelve todas.
name desc
login_timeout Segundos para la fase de conexion/login. Default 15. Evita que un host inalcanzable cuelgue.
name desc
query_timeout Segundos de timeout por query. Default 30.
Dict {columns: [nombres], rows: [{col: val}, ...], row_count: int} con el resultado de la SELECT. La conexion se cierra siempre antes de devolver. true
test_run_mssql_query_composes_connect_and_query
test_run_mssql_query_closes_connection_on_error
test_to_csv_renders_header_and_rows
python/functions/pipelines/run_mssql_query_test.py python/functions/pipelines/run_mssql_query.py

Ejemplo

Como API programatica (compone conexion + query + cierre):

import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "python", "functions"))
from pipelines.run_mssql_query import run_mssql_query

res = run_mssql_query(
    host="10.0.0.5",                 # IP LAN del Windows con SQL Server (no localhost desde WSL2)
    database="navdb",
    user="sa",
    password=os.environ["MSSQL_PASSWORD"],   # nunca literal: viene de pass/env
    sql="SELECT TOP 10 [No_], [Amount] FROM [dbo].[Cartera] WHERE [Customer No_] = %s",
    params=("CLI-0001",),            # binding seguro del driver, sin inyeccion
)
print(res["row_count"], res["columns"])
for fila in res["rows"]:
    print(fila)

Como comando one-shot para iterar sobre Navision (imprime JSON o CSV):

# La contrasena se lee de la env var, nunca se pasa por la linea de comandos
MSSQL_PASSWORD=$(pass navision/password) \
  ./fn run run_mssql_query \
    --host 10.0.0.5 --database navdb --user sa \
    --sql "SELECT TOP 5 [No_], [Amount] FROM [dbo].[Cartera] WHERE [Customer No_] = %s" \
    --param CLI-0001 \
    --format csv

Cuando usarla

Cuando quieras ejecutar una SELECT contra Navision (SQL Server) y ver las filas en un solo paso, sin abrir y cerrar la conexion a mano. Es la via rapida para iterar sobre una query (cartera / posted cartera, etc.): cambias el --sql, vuelves a lanzar, y lees el resultado. Para muchas queries seguidas sobre la misma conexion, usa directamente mssql_connect una vez + mssql_query N veces (este pipeline abre y cierra por llamada).

Gotchas

  • Conectividad WSL2 → Windows: --host debe ser la IP LAN del Windows que corre SQL Server, NO localhost (desde WSL2 localhost no alcanza al host Windows). Ver memoria wsl2-localhost-forwarding.
  • Credenciales: la contrasena se lee de la env var indicada por --password-env (default MSSQL_PASSWORD). Patron: MSSQL_PASSWORD=$(pass navision/password) ./fn run run_mssql_query .... --password literal existe pero esta DESACONSEJADO (queda visible en la lista de procesos). Nunca hardcodees credenciales.
  • Placeholders: usa %s / %(nombre)s (pymssql), NO ?. Pasa los valores por --param (posicional, repetible y en orden), jamas concatenados en el --sql (inyeccion).
  • Abre y cierra por llamada: cada invocacion abre una conexion nueva y la cierra al terminar (incluso si la query falla). No es eficiente para rafagas de muchas queries — para eso compon mssql_connect + mssql_query tu mismo.
  • Read-only: no hace commit. Pensado para SELECT. No lo uses para INSERT/UPDATE/DELETE.
  • Requiere pymssql instalado en el venv (lo importa mssql_connect).
  • CSV: --format csv serializa con el modulo csv estandar; valores no-string se convierten con str en JSON (default=str) para fechas/decimales de SQL Server.