Error al conectarse a MS SQL Server utilizando pyODBC, unixODBC y FreeTDS (en una Mac)

Recibo un error cuando bash conectarme a un servidor MS SQL en python, usando pyODBC -> unixODBC -> FreeTDS -> MS SQL stack. He dedicado mucho tiempo a esto, y hay algunos recursos excelentes si ha llegado a esta pregunta con problemas más fundamentales para lograr que una conexión funcione aquí y aquí .

Sin embargo, mi pregunta es sobre un error que (creo) está muy cerca de la meta de esta experiencia tan frustrante. Específicamente, este código en el cuaderno jupyter:

pyodbc.connect( 'DRIVER=/usr/local/lib/libtdsodbc.so;' 'SERVER=MyServerIP;' 'PORT=1433;' 'DATABASE= DatabaseName;' 'UID=MyUsername;' 'PWD=MyPassword') 

Me está dando este error:

 --------------------------------------------------------------------------- Error Traceback (most recent call last)  in () 1 pyodbc.connect( ----> 2 'DRIVER = /usr/local/lib/libtdsodbc.so;' 3 'SERVER = MyServerIP;' 4 'PORT = 1433;' 5 'DATABASE = DatabaseName' Error: ('HY000', '[] (20013) (SQLDriverConnect)') 

Y si sustituyo ‘DRIVER = / usr / local / lib / libtdsodbc.so;’ con ‘DRIVER = FreeTDS;’ Yo obtengo:

 --------------------------------------------------------------------------- Error Traceback (most recent call last)  in () 1 pyodbc.connect( ----> 2 'DRIVER=FreeTDS;' 3 'SERVER= MyServerIP;' 4 'PORT=1433;' 5 'DATABASE= DatabaseName;' Error: ('00000', '[00000] [iODBC][Driver Manager]dlopen(FreeTDS, 6): image not found (0) (SQLDriverConnect)') 

Lo que me lleva a creer que hay algo mal con la conexión unixODBC -> FreeTDS debido a la referencia a iODBC. Dicho de otra manera, a menos que proporcione específicamente una ruta al controlador FreeTDS, parece ignorar mis archivos odbcinst.ini y odbc.ini, que hacen referencia a FreeTDS y su ubicación como mi controlador (ver más abajo)

    Al ejecutar tsql e isql desde el terminal, ambos proporcionan buenas conexiones con el servidor.

    Sin embargo, cuando ejecuto el osql, aparece el siguiente error:

     $ osql -S MyServerIP -U MyUsername -P MyPassword checking shared odbc libraries linked to isql for default directories... /usr/local/bin/osql: line 53: ldd: command not found error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strings: can't open file: (No such file or directory) osql: problem: no potential directory strings in "/usr/local/bin/isql" osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix eg /usr/local isql strings are: checking odbc.ini files reading /Users/myname/.odbc.ini [MyServerIP] not found in /Users/myname/.odbc.ini cannot read "/odbc.ini" osql: error: unable to locate MyServerIP in any odbc.ini 

    Antecedentes de mi configuración

    Mi conexión fue construida (y reconstruida y reconstruida) usando los dos recursos vinculados en el primer párrafo y mi configuración completa se ve así:

    Ambiente

    Mac OSX 10.11.5

    Microsoft SQL Server 2012 – instancia de AWS EC2 (nube)

    Anaconda 4.0

    Python 3.5.1

    Cuaderno Jupyter 4.1.0

    Pila de conexión

    unixODBC – instalado usando homebrew

    FreeTDS: instalado usando homebrew con el comando: `$ brew install

    freetds –with-unixodbc`

    pyODBC 3.0.10 – instalado usando conda install

    MS SQL – instancia de AWS EC2 (nube)

    Archivos de referencia

    Mi archivo freetds.conf se lee así:

     [MYSERVERNAME] host = MyServerIP port = 1433 tds version = 7.3 client charset = UTF-8 

    Mi archivo odbcinst.ini se lee así:

     [FreeTDS] Description = TD Driver (MSSQL) Driver = /usr/local/lib/libtdsodbc.so Setup = /usr/local/lib/libtdsodbc.so FileUsage = 1 

    Mi archivo odbc.ini se lee así:

     [MYSERVERNAME] Driver = FreeTDS Server = MyServerIP Port = 1433 

    Estoy en una pérdida total, después de haber pasado muchas más horas de las que debería haber hecho en esto. Si alguien tiene alguna sugerencia, estaría siempre agradecido.

    Gracias.

    Hay muchas partes móviles en tu pregunta. No solo tiene Notebook-on-Python-on-ODBC, sino que también tiene iODBC y OS X. ¡Vaya!

    La pregunta se reduce a esto: ¿dónde busca odbc.ini ? No conozco una función ODBC que informe esa información.

    Debido a que es muy complicado, sugiero usar OS X dtruss (1). Capture la salida en un archivo y grep para odbc.ini y / o abra los comandos. Una vez que sepa dónde está mirando, puede poner su archivo allí y simplemente seguir las instrucciones. 😉

    La razón por la que el script osql no funciona en OS X es que a nadie le importó que funcionara, o se quejó de ello en la lista de correo de FreeTDS. El primer mensaje es un doozy:

    / usr / local / bin / osql: línea 53: ldd: comando no encontrado

    Yo trabajo alrededor de eso con

     $ command -V ldd ldd is aliased to `otool -L' 

    Eso podría ayudar. OTOH, el script fue escrito con unixODBC en mente, porque es mucho más popular.

    Aquí hay un ejemplo que creo que funcionaría para ti. Si está usando FreeTDS 0.95, puede usar la versión 7.3 de TDS, si está usando 0.82 o menos, use 7.1. Nunca me he molestado en probar osql con esta stack, si tsql e isql funcionan, debería poder hacer que el rest funcione, pero los matices de la configuración y la conexión son complicados:

    freetds.conf:

     [MYSERVERNAME] host = MYSERVERNAME.host.com port = 1433 tds version = 7.2 

    odbc.ini:

     [MYSERVERNAME] Driver = FreeTDS Server = MYSERVERNAME.host.com Port = 1433 TDS_Version = 7.2 

    odbcinst.ini:

     [FreeTDS] Description = TD Driver (MSSQL) Driver = /usr/local/lib/libtdsodbc.so 

    En Python:

     connection = pyodbc.connect(r'DRIVER={FreeTDS};SERVER=MYSERVERNAME.host.com;PORT=1433;DATABASE=Database name;UID=Database Username;PWD=DatabasePasswd;TDS_Version=7.2') 

    La versión 8.0 de TDS no existe. 7.2 es el más alto soportado en FreeTDS 0.91. Vea aquí para explicar la confusión: http://www.freetds.org/userguide/choosingtdsprotocol.htm

    Si todavía tiene problemas, intente realizar pruebas con tsql e isql para probar las capas FreeTDS y unixODBC de la stack de conexión respectivamente. ¡Buena suerte!

    Bueno, lo resolvimos, con la ayuda de mucha gente en esta página y aquí , persiguiendo un montón de callejones sin salida.

    Como (eventualmente) se sospechó, era el enlace pyodbc en la conexión. Estaba usando pyodbc v3.0.10, descargando desde el repository de paquetes de Anaconda. La solución fue v.3.0.9. Una vez que desinstalé v3.0.10, descargué v3.0.9 del repository de pypi y luego construí e instalé mi propio paquete conda … funcionó.

    Los pasos que tomé fueron los siguientes (tenga en cuenta que eran específicos de un entorno de anaconda):

     conda uninstall pyodbc conda skeleton pypi pyodbc --version 3.0.9 conda build pyodbc conda install pyodbc=3.0.9 --use-local 

    Una vez que volví a mi cuaderno Jupyter y ejecuté el mismo código anterior, se creó una buena conexión.

    No sé qué está mal con v.3.0.10, o si solo son los archivos que anaconda.org tiene en su repository. También he publicado algo en la página de github de pyodbc, pero no parece tan activo.

    De todos modos, gracias por la ayuda de todos. Espero que esto le salve a alguien algún tiempo.

    Solo desinstalé pyodbc y reinstalándolo de nuevo resolví el problema por mí.