关于python:使用pyODBC,unixODBC和FreeTDS(在Mac上)连接到MS SQL Server时出错

Error connecting to MS SQL Server using pyODBC, unixODBC and FreeTDS (on a Mac)

尝试使用pyODBC - > unixODBC - > FreeTDS - > MS SQL堆栈连接到python中的MS SQL服务器时出错。我花了很多时间在这上面,如果你已经达到了这个问题,并且有更多基本问题可以在这里和这里建立联系,那么我会有很多很好的资源。

但是,我的问题是关于一个错误(我认为)非常接近这个非常令人沮丧的经历的终点线。具体来说,这个代码在jupyter笔记本中:

1
2
3
4
5
6
7
pyodbc.connect(
    'DRIVER=/usr/local/lib/libtdsodbc.so;'
    'SERVER=MyServerIP;'
    'PORT=1433;'
    'DATABASE= DatabaseName;'
    'UID=MyUsername;'
    'PWD=MyPassword')

给我这个错误:

1
2
3
4
5
6
7
8
9
10
---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-7-d6b29b647116> in <module>()
      1 pyodbc.connect(
----> 2     'DRIVER = /usr/local/lib/libtdsodbc.so;'
      3     'SERVER = MyServerIP;'
      4     'PORT = 1433;'
      5     'DATABASE = DatabaseName'

Error: ('HY000', '[]  (20013) (SQLDriverConnect)’)

如果我替换'DRIVER = / usr / local / lib / libtdsodbc.so;' 'DRIVER = FreeTDS;'我明白了:

1
2
3
4
5
6
7
8
9
10
---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-12-607f0d66e615> in <module>()
      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)')

这让我相信unixODBC - > FreeTDS连接有问题,因为它引用了iODBC。换句话说,除非我专门提供FreeTDS驱动程序的路径,否则它似乎忽略了我的odbcinst.ini和odbc.ini文件,它们引用FreeTDS及其位置作为我的驱动程序(见下文)

从终端运行tsql和isql时,两者都可以与服务器建立良好的连接。

但是,当我运行osql时,我收到以下错误:

1
2
3
4
5
6
7
8
9
10
11
12
$ 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 e.g. /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

我的设置背景

我的连接使用第一段中链接的两个资源构建(并重建和重建),我的完整设置如下所示:

环境

Mac OSX 10.11.5

Microsoft SQL Server 2012 - AWS EC2实例(云)

Anaconda 4.0

Python 3.5.1

Jupyter笔记本4.1.0

连接堆栈

unixODBC - 使用自制软件安装

FreeTDS - 使用自制软件安装命令:`$ brew install

freetds --with-unixodbc`

pyODBC 3.0.10 - 使用conda install安装

MS SQL - AWS EC2实例(云)

参考文件

我的freetds.conf文件如下所示:

1
2
3
4
5
[MYSERVERNAME]
    host = MyServerIP
    port = 1433
    tds version = 7.3
    client charset = UTF-8

我的odbcinst.ini文件如下所示:

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

我的odbc.ini文件如下所示:

1
2
3
4
[MYSERVERNAME]
Driver = FreeTDS
Server = MyServerIP
Port = 1433

我完全失去了,我花了比我应该多得多的时间。如果有人有任何建议,我将永远感激不尽。

谢谢。


你的问题中有很多活动部分。您不仅拥有基于ODBC的Python上的Notebook,而且还拥有iODBC和OS X.哎呀!

问题归结为:iODBC在哪里寻找odbc.ini?我不知道报告该信息的ODBC函数。

因为它很复杂,我建议使用OS X dtruss(1)。将输出捕获到文件,然后grep for odbc.ini和/或打开命令。一旦你知道它在哪里,你可以把你的文件放在那里,然后按照指示。 ;-)

osql脚本在OS X上不起作用的原因是没有人关心它的工作,或者曾经在FreeTDS邮件列表上抱怨它。第一条消息是doozy:

/usr/local/bin/osql: line 53: ldd: command not found

我解决这个问题

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

这可能有所帮助。 OTOH,脚本是用unixODBC编写的,因为它更受欢迎。


只需卸载pyodbc并重新安装它就可以解决我的问题。


好吧,我们解决了它 - 在这个页面上的很多人的帮助下,在这里,追逐了很多盲道。

(最终)怀疑,这是连接中的pyodbc链接。我正在使用pyodbc v3.0.10,从Anaconda软件包库下载。解决方案是v.3.0.9。一旦我卸载了v3.0.10,从pypi存储库下载了v3.0.9,然后构建并安装了我自己的conda软件包......就可以了。

我采取的步骤如下(注意这些特定于anaconda环境):

1
2
3
4
5
6
7
conda uninstall pyodbc

conda skeleton pypi pyodbc --version 3.0.9

conda build pyodbc

conda install pyodbc=3.0.9 --use-local

一旦我回到我的Jupyter笔记本并运行上面相同的代码,它就创建了一个良好的连接。

我不知道v.3.0.10有什么问题,或者它只是anaconda.org在其存储库中的文件。我也在pyodbc github页面上发布了一些内容,但它看起来并不活跃。

无论如何,谢谢大家的帮助。我希望这能节省一些时间。


这是我认为适合你的一个例子。如果您使用的是FreeTDS 0.95,则可以使用TDS版本7.3,如果您使用的是0.82或更低,请使用7.1。我从来没有打扰用这个堆栈测试osql,如果tsqlisql工作,你应该能够让其余的工作,但配置和连接的细微差别是棘手的:

freetds.conf:

1
2
3
4
[MYSERVERNAME]
    host = MYSERVERNAME.host.com
    port = 1433
    tds version = 7.2

ODBC.INI:

1
2
3
4
5
[MYSERVERNAME]
    Driver = FreeTDS
    Server = MYSERVERNAME.host.com
    Port = 1433
    TDS_Version = 7.2

ODBCINST.INI:

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

在Python中:

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

TDS版本8.0不存在。 7.2是FreeTDS 0.91中支持的最高值。请参阅此处以解释混淆:http://www.freetds.org/userguide/choosingtdsprotocol.htm

如果您仍然遇到问题,请尝试使用tsqlisql进行测试,分别测试连接堆栈的FreeTDS和unixODBC层。祝好运!