--- name: mssql_connect kind: function lang: py domain: infra version: "1.0.0" purity: impure signature: "def mssql_connect(host: str, database: str, user: str, password: str, port: int = 1433, login_timeout: int = 15, query_timeout: int = 30) -> pymssql.Connection" description: "Abre una conexion pymssql a un Microsoft SQL Server (donde corre Navision). Las credenciales llegan siempre por argumento (el caller las saca de pass/env), nunca hardcodeadas. login_timeout acota la fase de conexion/login para evitar cuelgues con un host inalcanzable. Devuelve el objeto conexion pymssql para iterar queries despues." tags: [mssql, sqlserver, navision, sql-connect, infra] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [pymssql] params: - name: host desc: "Host o IP del servidor SQL Server. Desde WSL2 debe ser la IP LAN de Windows (ej. 10.0.0.5), no localhost." - name: database desc: "Nombre de la base de datos a la que conectar (ej. navdb)." - name: user desc: "Usuario de login de SQL Server (ej. sa)." - name: password desc: "Contrasena del usuario de login. Se pasa desde pass/env, nunca como literal." - name: port desc: "Puerto TCP del SQL Server. Por defecto 1433. La funcion lo convierte a string porque pymssql lo exige asi." - name: login_timeout desc: "Segundos permitidos para la fase de conexion/login antes de fallar. Por defecto 15. Evita que un host inalcanzable cuelgue indefinidamente." - name: query_timeout desc: "Segundos permitidos para cada query ejecutada sobre la conexion devuelta antes de hacer timeout. Por defecto 30." output: "Un objeto pymssql.Connection abierto. El caller es responsable de cerrarlo con .close() al terminar." tested: true tests: ["test_golden_connect_passes_string_port_and_kwargs", "test_error_path_wraps_failure_with_host"] test_file_path: "python/functions/infra/mssql_connect_test.py" file_path: "python/functions/infra/mssql_connect.py" --- ## Ejemplo ```python import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "python", "functions")) from infra.mssql_connect import mssql_connect # La IP debe ser la IP LAN del servidor Windows: desde WSL2 "localhost" NO # llega al host Windows. La contrasena llega del entorno, nunca literal. conn = mssql_connect( host="10.0.0.5", database="navdb", user="sa", password=os.environ["MSSQL_PASSWORD"], port=1433, login_timeout=15, ) try: with conn.cursor() as cur: cur.execute("SELECT TOP 1 name FROM sys.databases") print(cur.fetchone()) finally: conn.close() ``` ## Cuando usarla Usala cuando necesites abrir una conexion a un Microsoft SQL Server (donde corre Navision) antes de iterar queries con `mssql_query`. Es el primer paso de cualquier pipeline que lea datos de Navision: abre la conexion una vez, reutilizala para varias queries, y cierrala al final. Triggers: "conecta a Navision", "lee de SQL Server", "abre conexion mssql". ## Gotchas - WSL2 -> Windows: usa la IP LAN del servidor Windows, NUNCA `localhost`. Desde dentro de WSL2 `localhost` no alcanza el host Windows (el reenvio de localhost solo funciona Windows -> WSL, no al reves). - pymssql necesita el puerto como string. La funcion ya convierte `port` a `str(port)` internamente, asi que tu pasas un int normal. - `login_timeout` esta acotado (15s por defecto) precisamente para que un host inalcanzable o mal configurado falle con un RuntimeError claro en vez de colgarse indefinidamente. Ajustalo si la red es lenta, pero no lo dejes sin limite. - Credenciales NUNCA hardcodeadas: `user`/`password` llegan por argumento desde `pass`/env. No las escribas literales en el codigo del caller. - Cierra la conexion con `.close()` al terminar (idealmente en un `finally`). La funcion devuelve un handle abierto y no gestiona su ciclo de vida. - Requiere `pymssql` instalado en el venv (import perezoso: el modulo importa sin la dependencia, pero la llamada falla con RuntimeError claro si falta).