【问题标题】:Error connecting to MS SQL Server using pyODBC, unixODBC and FreeTDS (on a Mac)使用 pyODBC、unixODBC 和 FreeTDS(在 Mac 上)连接到 MS SQL Server 时出错
【发布时间】:2016-10-22 08:23:10
【问题描述】:

尝试使用 pyODBC --> unixODBC --> FreeTDS --> MS SQL 堆栈在 python 中连接到 MS SQL 服务器时出现错误。我在这方面花了很多时间,如果您遇到这个问题更基本的问题是与工作 herehere 建立联系,那么这里有一些很好的资源。

但是,我的问题是关于(我认为)非常接近这种非常令人沮丧的体验的终点线的错误。具体来说,jupyter notebook 中的这段代码:

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

给我这个错误:

---------------------------------------------------------------------------
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;'使用“驱动程序=FreeTDS;”我明白了:

---------------------------------------------------------------------------
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 时,出现以下错误:

$ 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 Notebook 4.1.0

连接堆栈

unixODBC – 使用自制软件安装

FreeTDS – 使用 homebrew 命令安装:`$ brew install

freetds --with-unixodbc`

pyODBC 3.0.10 – 使用 conda install 安装

MS SQL – AWS EC2 实例(云)

参考文件

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

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

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

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

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

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

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

谢谢。

【问题讨论】:

  • 查看my answer 对另一个问题是否有帮助 - 并尝试 TDS 版本 = 8.0...
  • 感谢@BennyHill,严格按照链接中的说明操作导致我无法通过 isql 命令建立连接。如上所述,我的 tsql 和 isql 测试都创建了连接。我越来越相信这与 pyODBC --> unixODBC 连接失败有关。但不知道是什么。
  • 两件事,(1) 请在您的 pyodbc.connect() 中使用 DRIVER={FreeTDS} 和 (2) 不要使用 TDS 8.0 版本,它不是真正的 TDS 版本。见:freetds.org/userguide/choosingtdsprotocol.htm
  • 进行了您建议的更改,但没有任何乐趣。正如我在下面的评论中一样,而且还在 FreeTDS 周围添加了大括号。同样的错误:Error: ('00000', '[00000] [iODBC][Driver Manager]dlopen({FreeTDS}, 6): image not found (0) (SQLDriverConnect)')

标签: python sql-server pyodbc freetds unixodbc


【解决方案1】:

您的问题中有很多变化的部分。您不仅有 Notebook-on-Python-on-ODBC,而且还有 iODBC 和 OS X。哎呀!

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

因为它太复杂了,我建议使用 OS X dtruss(1)。将输出捕获到文件中,然后 grep 获取 odbc.ini 和/或 open 命令。一旦你知道它在哪里寻找,你就可以把你的文件放在那里,然后按照指示进行操作。 ;-)

osql 脚本不能在 OS X 上运行的原因是没有人愿意让它工作,或者从来没有在 FreeTDS 邮件列表上抱怨过它。第一条消息很糟糕:

/usr/local/bin/osql:第 53 行:ldd:找不到命令

我用

来解决这个问题
$ command -V ldd
ldd is aliased to `otool -L'

这可能会有所帮助。 OTOH,该脚本是在考虑 unixODBC 的情况下编写的,因为它更受欢迎。

【讨论】:

  • 谢谢詹姆斯,非常有帮助,我会听从您的指导。一个警告:我不想使用 iODBC。我正在尝试使用 unixODBC,因为正如您所指出的,它似乎更受欢迎/得到更好的支持。但是,基于我上面提到的第二个错误,pyODBC (v 3.0.10) 似乎正在使用 iODBC。我不知道为什么。这让我很难过。
  • 是的,许多活动部件。但我不认为我的设置有那么奇怪,是吗?我只是一个使用 mac 的人,尝试使用 jupyter notebook 将 sql 表读入 pandas 数据帧。如果有更简单的方法,请告诉我。
  • 我已将我的问题缩小到我认为的问题,这里:stackoverflow.com/questions/37947482/…
【解决方案2】:

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

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

在 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')

TDS 8.0 版不存在。 7.2 是 FreeTDS 0.91 中支持的最高版本。看到这里解释混淆:http://www.freetds.org/userguide/choosingtdsprotocol.htm

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

【讨论】:

  • 感谢 FlipperPA,但不高兴。我已经尝试了所有 FreeTDS 版本(7.0、7.2、7.3 和 8.0,以防万一),但都没有奏效。将您的语法用于 3 个文件和 python 代码(两次),我得到了似乎引用 iODBC 错误的相同错误。还测试了 isql 和 sql 并能够与两者连接。这似乎是一个 pyodbc 问题。
  • 当您执行tsql -C 时,它是否对 iODBC 和 unixodbc 都说“是”?要测试 iODBC 连接性,我相信您应该使用类似于iodbc/samples 中的isqlodbctest 命令。是否正在卸载 iODBC 和选项(如果有)?
  • 对 unixodbc 是,对 iODBC 不是。哪个好,对吧? Version: freetds v1.00 freetds.conf directory: /usr/local/Cellar/freetds/1.00/etc MS db-lib source compatibility: no Sybase binary compatibility: no Thread safety: yes iconv library: yes TDS version: 7.3 iODBC: no unixodbc: yes ...
  • 我考虑过卸载 iODBC。但我知道这可能会破坏很多其他东西,因为很多商业软件都在使用它。另外,pyodbc 正在寻找 iODBC 似乎很明显,我不确定摆脱它会导致它默认为 unixODBC。我猜它只会说 iODBC 丢失了。系统中是否还有其他东西可以覆盖 pyodbc 查找其驱动程序的内容或位置?
  • 我在 FreeTDS 上见过很多,但这是一个新的。我也没有接触过 FreeTDS 1.0。你有机会用 0.95 版试试吗?老实说,我在这里抓住了稻草。
【解决方案3】:

嗯,我们解决了这个问题——在这个页面上和here 上的很多人的帮助下,追了很多死胡同。

正如(最终)怀疑的那样,它是连接中的 pyodbc 链接。我正在使用 pyodbc v3.0.10,通过从 Anaconda 包存储库下载。解决方案是 v.3.0.9。一旦我卸载了 v3.0.10,从 pypi 存储库下载了 v3.0.9,然后构建并安装了我自己的 conda 包......它工作了。

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

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 页面上发布了一些内容,但它看起来并不那么活跃。

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 2018-01-30
      • 2016-10-21
      • 2013-05-31
      • 2020-07-20
      相关资源
      最近更新 更多