无法在 Mac 上导入 pyodbc
Cannot import pyodbc on Mac
我无法在我的 Macbook Pro(运行 Mac OS X 10.10.5)和 python 版本 2.7.10。我是用pip
获取的,我的是最新版本(3.0.10)。它给了我以下错误:
$ python
Python 2.7.10 (default, Jul 14 2015, 19:46:27)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyodbc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(/Library/Python/2.7/site-packages/pyodbc.so, 2): Symbol not found: _SQLAllocHandle
Referenced from: /Library/Python/2.7/site-packages/pyodbc.so
Expected in: flat namespace
in /Library/Python/2.7/site-packages/pyodbc.so
在过去的几个月里,我尝试了几件事都无济于事,包括自己构建它(并(重新)安装 iodbc
和 unixodbc
)。
一件奇怪的事情是 none 我尝试使用的其他 python 数据库包(例如,sqlalchemy、pypyodbc 等)出于各种相似的原因而工作任何一个。这让我怀疑我的 ODBC 驱动程序或库存在一些潜在问题,但我不知道如何诊断它。
我在一个共享代码环境中工作,团队的其他成员通过 Windows 使用 pyodbc
,我 真的 现在需要它来工作.任何帮助或建议将不胜感激!
**在回复 mauro 的回答时添加了更多详细信息。注意,下面的第二次更新改变了一些事情。 **
这里有一些我应该包含在原始问题中的更多细节。
首先,这是 mauro 在我的机器上询问的命令的结果。
$ odbc_config --version
2.3.2
$ odbc_config --libs
-L/usr/local/Cellar/unixodbc/2.3.2_1/lib -lodbc
$ odbc_config --odbcini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini
$ odbc_config --odbcinstini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
我对 "Cellar" 部分持怀疑态度,所以我查看了 mauro 答案中的路径,它们似乎都指向 Cellar(自制软件?):
$ ls -al /usr/local/etc/*odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
$ ls -al /usr/local/etc/odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
1395:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/etc/*odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
1396:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/lib/*odbc*
lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbc.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.2.dylib
lrwxr-xr-x 1 ***** admin 44 17 Aug 16:57 /usr/local/lib/libodbc.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.dylib
lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbccr.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.2.dylib
lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbccr.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.dylib
lrwxr-xr-x 1 ***** admin 50 17 Aug 16:57 /usr/local/lib/libodbcinst.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.2.dylib
lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbcinst.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.dylib
lrwxr-xr-x 1 ***** admin 45 17 Aug 16:59 /usr/local/lib/libtdsodbc.0.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.0.so
lrwxr-xr-x 1 ***** admin 42 17 Aug 16:59 /usr/local/lib/libtdsodbc.a@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.a
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:59 /usr/local/lib/libtdsodbc.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.so
/usr/local/lib/tdbcodbc1.0.0:
total 144
drwxr-xr-x 5 root wheel 170 29 Mar 2013 ./
drwxrwxr-x 44 root admin 1496 17 Aug 16:59 ../
-rwxr-xr-x 1 root wheel 49796 29 Mar 2013 libtdbcodbc1.0.0.dylib*
-r--r--r-- 1 root wheel 245 29 Mar 2013 pkgIndex.tcl
-r--r--r-- 1 root wheel 15624 29 Mar 2013 tdbcodbc.tcl
我可以通过 tsql
(细节匿名)很好地连接到 DNS:
$ tsql -S servername.myserver.com -U me -P mypw -D testdb
locale is "en_CA.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting testdb as default database in login packet
1>
但是osql
和isql
都会出现问题:
$ isql -v MyDSN me mypw
[S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source
[01000][unixODBC][FreeTDS][SQL Server]Unknown host machine name.
[ISQL]ERROR: Could not SQLConnect
这个提供的信息最多。它至少在我的 ~/.odbc.ini
文件中找到了 DSN 条目。
$ osql -S MyDSN -U ***** -P *****
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/*****/.odbc.ini
[MyDSN] found in /Users/*****/.odbc.ini
found this section:
[MyDSN]
Description = testdb SQLServer DB
Driver = FreeTDS
Trace = Yes
TraceFile = /tmp/sql.log
Database = Places
ServerName = *****
UserName = *****
Password = *****
Port = 1433
Protocol = 7.2
ReadOnly = No
RowVersioning = No
ShowSystemTables = No
ShowOidColumn = No
FakeOidIndex = No
looking for driver for DSN [*****] in /Users/*****/.odbc.ini
found driver line: " Driver = FreeTDS"
driver "FreeTDS" found for [*****] in .odbc.ini
found driver named "FreeTDS"
"FreeTDS" is not an executable file
looking for entry named [FreeTDS] in /odbcinst.ini
grep: /odbcinst.ini: No such file or directory
我不确定如何解决 isql
报告的问题,但这似乎表明我的 odbc 配置有误。不幸的是,我很抱歉我不知道/记得我究竟做了什么才能以这种方式得到它——几周来我一直在认真地断断续续地尝试各种与此相关的事情。
mauro 评论后的第二次更新。
我取得了一些进步。我重新安装了 unixODBC 和 freeTDS(直接从 http://www.unixodbc.org/ and http://www.freetds.org/ 而不是使用自制软件),然后我的 odbc_config
命令的输出与 mauro 的输出相匹配。
在尝试了一些我的路径之后,我能够获得 osql
和 isql
以成功连接到我的 SQL 服务器实例。 (我发现之前失败的一个原因是因为我组织中的 IT 部门在 LAN 上阻止所有流向端口 1433 的流量。当我像我的 Windows 同事一样切换到 Wifi 时,它起作用了。 ) 我认为这是一个很大的进步!
但是,当我再次尝试从 python 中导入 pyodbc 时,我收到了与开始时完全相同的错误消息。叹。所以任何其他想法仍然会受到赞赏!
我同意...在我看来,首先要检查的是底层 ODBC 层。
您说您已经从 Mac 上的源代码安装了 unixODBC(就像我一样)。所以使用 odbc_config 检查主要的 unixODBC 参数(你应该在 /usr/local/bin
下):
$ odbc_config --version
2.3.4
$ odbc_config --libs
-L/usr/local/lib -lodbc
$ odbc_config --odbcini
/usr/local/etc/odbc.ini
$ odbc_config --odbcinstini
/usr/local/etc/odbcinst.ini
然后 - 我猜 - 您已经为您的 ODBC 数据库创建了一个数据源。使用另一个 unixODBC 实用程序 (isql
) 检查是否可以通过 ODBC 连接到数据库:
$ sql <your_DSN> <your_DB_user> <your_DB_password> -v
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> quit
如果一切正常,则 unixODBC 层正常。
更新
嗯……你收到这条消息:
...
checking odbc.ini files
reading /Users/*****/.odbc.ini
[MyDSN] found in /Users/*****/.odbc.ini
...
但 unixODBC 报告的 odic.ini 位置不同:
$ odbc_config --odbcini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini
我还会检查 pyodbc 使用了哪些库。这是我的:
$ otool -L /Library/Python/2.7/site-packages/pyodbc.so
/Library/Python/2.7/site-packages/pyodbc.so:
/usr/local/lib/libodbc.2.dylib (compatibility version 3.0.0, current version 3.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
如您所见,我的 pyodbc 使用安装在 /usr/local/lib
下的 libodbc。正是 odic_config 在我的案例中报告的位置。
第二次更新
进展顺利!因此,总而言之,当前状态是:
isql DSN USER PASSWORD
按预期工作
import pyodbc
returns 找不到 _SQLAllocHandle 符号。这意味着它没有找到正确的库
otool -L ...pyodbc.so
(与二分之一的路径相同?)指向正确的库
如果是这种情况,我会 re-install pyodbc(我确实使用了 pip
)。我听说旧版本在找到正确的 headers/libs 时遇到问题。现在 isql
可以工作了……pyodbc 也应该可以工作了。
首先,感谢 @mauro 提供 his/her 有用且坚持不懈的建议。
经过几个月的用头撞墙,昨晚我终于能够让它工作了!
在这里,我概述了一些(对我来说)关键的事情,希望这些可能对其他和我有同样困境的人有用。
BG。前一段时间(一个多月),我阅读并尝试做建议 here 的事情。虽然我不记得当时我尝试过的每件事,但这让我开始 tsql
工作,而且我认为,我安装了 unixODBC
和 freeTDS
的 Homebrew 版本。
从我提出上面的问题开始,以下是我尝试过的一些似乎有影响的事情。 (我不确定哪些事情特别重要,所以我把所有事情都包括在内。)第 1 点和第 2 点已在上面描述,所以我不会详述它们。
我。我 re-installed unixODBC
和 freeTDS
来自他们的项目网站。
二.我发现我的 LAN 上的 1433 端口被阻止了,所以我切换到未被阻止的 WiFi。
这两件事让我能够让 isql
和 osql
工作。
三。由于类似于动态链接错误的原因,pyodbc
无法在 python 中导入。我尝试使用 dl.open()
和 ctype.cdll.LoadLibrary()
直接加载 /usr/local/lib/libodbc.dylib
。在这两种情况下,我都收到一条错误消息:
dl.error: dlopen(libodbc.dylib, 6): no suitable image found. Did find:
/usr/local/lib/libodbc.dylib: mach-o, but wrong architecture
经过一些挖掘,thie 引导我重新编译 unixODBC
32 位而不是 64 位 ,如下所示:
sudo ./configure CFLAGS="-m32 -arch i386 -O2" LDFLAGS="-m32 -arch i386" CXXFLAGS="-m32 -arch i386"
sudo make
sudo make install
那时,我可以使用 dl.open()
显式加载 libodbc.dylib
并且 最终 导入 pyodbc!!
四.不幸的是,没有通过 dl.open()
显式加载,导入仍然失败。这让我尝试使用我的 LD_LIBRARY_PATH
(建议 here),但似乎还没有任何效果。所以我仍然坚持使用 dl.open()
hack。
此外,它仍然没有工作,当我尝试连接到数据源时失败与 freeTDS
驱动程序有关。这最终让我想到了以下 "working" hack-around:
import sys
if (sys.platform == 'darwin'):
import dl
_lib1 = dl.open("libodbc.dylib") # Found in /usr/local/lib
_lib2 = dl.open("/opt/local/lib/libtdsodbc.so")
import pyodbc
请注意,必须使用全局变量 _lib1
和 _lib2
才能使其正常工作(我认为是为了保持内容加载)。
至此,一切似乎终于运行良好,我可以使用 pyodbc
!!
一路上我又尝试了一些东西,但我不清楚它们是否有帮助。
我也尝试在 32 位模式下编译 freeTDS
,类似于我为 unixODBC
所做的,但我不确定是否有效。
我从 github 存储库下载、构建并安装了 pyodbc
,而不是使用 pip
。 (它与 pip
提供的版本相同 -- 3.0.10。)
根据评论 #10 here,我在 pyodbc
源下载(下方)中的 setup.py
的 darwin
案例中添加了两行和 re-ran python.py setup.py build install
.
喜欢:
elif sys.platform == 'darwin':
# The latest versions of OS X no longer ship with iodbc. Assume
# unixODBC for now.
settings['libraries'].append('odbc')
settings['include_dirs'] = ['/opt/local/include'] # Added this line
settings['library_dirs'] = ['/opt/local/lib'] # Added this line
# Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot*
settings['extra_compile_args'].extend([
'-Wno-write-strings',
'-Wno-deprecated-declarations'
])
# Apple has decided they won't maintain the iODBC system in OS/X and has added deprecation warnings in 10.8.
# For now target 10.7 to eliminate the warnings.
settings['define_macros'].append( ('MAC_OS_X_VERSION_10_7',) )
settings['include_dirs'] = ['/opt/local/include']
settings['library_dirs'] = ['/opt/local/lib']
- 全部完成后,我进行了检查,我还能够导入和使用
pypyodbc
而无需 使用 dl.open()
技巧。我不确定是否需要上述所有步骤才能实现。我怀疑主要问题是库的 32 位与 64 位版本。
最后,虽然这与我无法 pyodbc
导入的原因无关,但我会添加一条注释,说明导致我损失了将近一个小时的事情。在某些时候,我试图按照 this site. However, I later discovered that the non-DSN connection string that the author showed did not work. I instead had to use the FreeTDS connection attributes shown here 上的(非常有帮助的)说明进行操作。例如:
"DRIVER=FreeTDS;Server=*****;Port=1433;TDS_Version=7.2;Database=*****;UID=*****;PWD=*****"
虽然现在大部分情况下都对我有用,但我应该提一下,对于我的一些查询游标,我现在有时也会遇到以下错误,但我认为这与任何一个都无关以上。 (相反,我怀疑连接上存在某种 "timeout" 问题。...)
...
for row in cursor:
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1920, in next
row = self.fetchone()
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1914, in fetchone
check_success(self, ret)
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 986, in check_success
ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 966, in ctrl_err
raise DatabaseError(state,err_text)
pypyodbc.DatabaseError: (u'08S01', u'[08S01] [FreeTDS][SQL Server]Bad token from the server: Datastream processing out of sync')
Exception pypyodbc.DatabaseError: DatabaseError(u'08S01', u'[08S01] [FreeTDS][SQL Server]Write to the server failed') in <bound method Connection.__del__ of <pypyodbc.Connection instance at 0x60d5a8>> ignored
总而言之,我认为至少有 3 个(如果不是 4 个)我不能在 python 中使用 pyodbc
的原因。主要的两个与 unixODBC
的 32 位与 64 位编译和一些我仍然不太明白的库导入路径问题有关。
祝所有必须努力完成所有这些的人好运!
或者……
brew install unixodbc
我无法在我的 Macbook Pro(运行 Mac OS X 10.10.5)和 python 版本 2.7.10。我是用pip
获取的,我的是最新版本(3.0.10)。它给了我以下错误:
$ python
Python 2.7.10 (default, Jul 14 2015, 19:46:27)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyodbc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(/Library/Python/2.7/site-packages/pyodbc.so, 2): Symbol not found: _SQLAllocHandle
Referenced from: /Library/Python/2.7/site-packages/pyodbc.so
Expected in: flat namespace
in /Library/Python/2.7/site-packages/pyodbc.so
在过去的几个月里,我尝试了几件事都无济于事,包括自己构建它(并(重新)安装 iodbc
和 unixodbc
)。
一件奇怪的事情是 none 我尝试使用的其他 python 数据库包(例如,sqlalchemy、pypyodbc 等)出于各种相似的原因而工作任何一个。这让我怀疑我的 ODBC 驱动程序或库存在一些潜在问题,但我不知道如何诊断它。
我在一个共享代码环境中工作,团队的其他成员通过 Windows 使用 pyodbc
,我 真的 现在需要它来工作.任何帮助或建议将不胜感激!
**在回复 mauro 的回答时添加了更多详细信息。注意,下面的第二次更新改变了一些事情。 **
这里有一些我应该包含在原始问题中的更多细节。
首先,这是 mauro 在我的机器上询问的命令的结果。
$ odbc_config --version
2.3.2
$ odbc_config --libs
-L/usr/local/Cellar/unixodbc/2.3.2_1/lib -lodbc
$ odbc_config --odbcini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini
$ odbc_config --odbcinstini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
我对 "Cellar" 部分持怀疑态度,所以我查看了 mauro 答案中的路径,它们似乎都指向 Cellar(自制软件?):
$ ls -al /usr/local/etc/*odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
$ ls -al /usr/local/etc/odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
1395:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/etc/*odbc*
lrwxr-xr-x 1 ***** admin 39 17 Aug 16:57 /usr/local/etc/odbc.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbc.ini
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:57 /usr/local/etc/odbcinst.ini@ -> ../Cellar/unixodbc/2.3.2_1/etc/odbcinst.ini
1396:Stephens-BlueDot-MacBook-Pro:~/BlueDot/Code/Data Processing Tools} ls -al /usr/local/lib/*odbc*
lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbc.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.2.dylib
lrwxr-xr-x 1 ***** admin 44 17 Aug 16:57 /usr/local/lib/libodbc.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbc.dylib
lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbccr.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.2.dylib
lrwxr-xr-x 1 ***** admin 46 17 Aug 16:57 /usr/local/lib/libodbccr.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbccr.dylib
lrwxr-xr-x 1 ***** admin 50 17 Aug 16:57 /usr/local/lib/libodbcinst.2.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.2.dylib
lrwxr-xr-x 1 ***** admin 48 17 Aug 16:57 /usr/local/lib/libodbcinst.dylib@ -> ../Cellar/unixodbc/2.3.2_1/lib/libodbcinst.dylib
lrwxr-xr-x 1 ***** admin 45 17 Aug 16:59 /usr/local/lib/libtdsodbc.0.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.0.so
lrwxr-xr-x 1 ***** admin 42 17 Aug 16:59 /usr/local/lib/libtdsodbc.a@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.a
lrwxr-xr-x 1 ***** admin 43 17 Aug 16:59 /usr/local/lib/libtdsodbc.so@ -> ../Cellar/freetds/0.95.18/lib/libtdsodbc.so
/usr/local/lib/tdbcodbc1.0.0:
total 144
drwxr-xr-x 5 root wheel 170 29 Mar 2013 ./
drwxrwxr-x 44 root admin 1496 17 Aug 16:59 ../
-rwxr-xr-x 1 root wheel 49796 29 Mar 2013 libtdbcodbc1.0.0.dylib*
-r--r--r-- 1 root wheel 245 29 Mar 2013 pkgIndex.tcl
-r--r--r-- 1 root wheel 15624 29 Mar 2013 tdbcodbc.tcl
我可以通过 tsql
(细节匿名)很好地连接到 DNS:
$ tsql -S servername.myserver.com -U me -P mypw -D testdb
locale is "en_CA.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting testdb as default database in login packet
1>
但是osql
和isql
都会出现问题:
$ isql -v MyDSN me mypw
[S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source
[01000][unixODBC][FreeTDS][SQL Server]Unknown host machine name.
[ISQL]ERROR: Could not SQLConnect
这个提供的信息最多。它至少在我的 ~/.odbc.ini
文件中找到了 DSN 条目。
$ osql -S MyDSN -U ***** -P *****
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/*****/.odbc.ini
[MyDSN] found in /Users/*****/.odbc.ini
found this section:
[MyDSN]
Description = testdb SQLServer DB
Driver = FreeTDS
Trace = Yes
TraceFile = /tmp/sql.log
Database = Places
ServerName = *****
UserName = *****
Password = *****
Port = 1433
Protocol = 7.2
ReadOnly = No
RowVersioning = No
ShowSystemTables = No
ShowOidColumn = No
FakeOidIndex = No
looking for driver for DSN [*****] in /Users/*****/.odbc.ini
found driver line: " Driver = FreeTDS"
driver "FreeTDS" found for [*****] in .odbc.ini
found driver named "FreeTDS"
"FreeTDS" is not an executable file
looking for entry named [FreeTDS] in /odbcinst.ini
grep: /odbcinst.ini: No such file or directory
我不确定如何解决 isql
报告的问题,但这似乎表明我的 odbc 配置有误。不幸的是,我很抱歉我不知道/记得我究竟做了什么才能以这种方式得到它——几周来我一直在认真地断断续续地尝试各种与此相关的事情。
mauro 评论后的第二次更新。
我取得了一些进步。我重新安装了 unixODBC 和 freeTDS(直接从 http://www.unixodbc.org/ and http://www.freetds.org/ 而不是使用自制软件),然后我的 odbc_config
命令的输出与 mauro 的输出相匹配。
在尝试了一些我的路径之后,我能够获得 osql
和 isql
以成功连接到我的 SQL 服务器实例。 (我发现之前失败的一个原因是因为我组织中的 IT 部门在 LAN 上阻止所有流向端口 1433 的流量。当我像我的 Windows 同事一样切换到 Wifi 时,它起作用了。 ) 我认为这是一个很大的进步!
但是,当我再次尝试从 python 中导入 pyodbc 时,我收到了与开始时完全相同的错误消息。叹。所以任何其他想法仍然会受到赞赏!
我同意...在我看来,首先要检查的是底层 ODBC 层。
您说您已经从 Mac 上的源代码安装了 unixODBC(就像我一样)。所以使用 odbc_config 检查主要的 unixODBC 参数(你应该在 /usr/local/bin
下):
$ odbc_config --version
2.3.4
$ odbc_config --libs
-L/usr/local/lib -lodbc
$ odbc_config --odbcini
/usr/local/etc/odbc.ini
$ odbc_config --odbcinstini
/usr/local/etc/odbcinst.ini
然后 - 我猜 - 您已经为您的 ODBC 数据库创建了一个数据源。使用另一个 unixODBC 实用程序 (isql
) 检查是否可以通过 ODBC 连接到数据库:
$ sql <your_DSN> <your_DB_user> <your_DB_password> -v
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> quit
如果一切正常,则 unixODBC 层正常。
更新
嗯……你收到这条消息:
...
checking odbc.ini files
reading /Users/*****/.odbc.ini
[MyDSN] found in /Users/*****/.odbc.ini
...
但 unixODBC 报告的 odic.ini 位置不同:
$ odbc_config --odbcini
/usr/local/Cellar/unixodbc/2.3.2_1/etc/odbc.ini
我还会检查 pyodbc 使用了哪些库。这是我的:
$ otool -L /Library/Python/2.7/site-packages/pyodbc.so
/Library/Python/2.7/site-packages/pyodbc.so:
/usr/local/lib/libodbc.2.dylib (compatibility version 3.0.0, current version 3.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
如您所见,我的 pyodbc 使用安装在 /usr/local/lib
下的 libodbc。正是 odic_config 在我的案例中报告的位置。
第二次更新
进展顺利!因此,总而言之,当前状态是:
isql DSN USER PASSWORD
按预期工作import pyodbc
returns 找不到 _SQLAllocHandle 符号。这意味着它没有找到正确的库otool -L ...pyodbc.so
(与二分之一的路径相同?)指向正确的库
如果是这种情况,我会 re-install pyodbc(我确实使用了 pip
)。我听说旧版本在找到正确的 headers/libs 时遇到问题。现在 isql
可以工作了……pyodbc 也应该可以工作了。
首先,感谢 @mauro 提供 his/her 有用且坚持不懈的建议。
经过几个月的用头撞墙,昨晚我终于能够让它工作了!
在这里,我概述了一些(对我来说)关键的事情,希望这些可能对其他和我有同样困境的人有用。
BG。前一段时间(一个多月),我阅读并尝试做建议 here 的事情。虽然我不记得当时我尝试过的每件事,但这让我开始 tsql
工作,而且我认为,我安装了 unixODBC
和 freeTDS
的 Homebrew 版本。
从我提出上面的问题开始,以下是我尝试过的一些似乎有影响的事情。 (我不确定哪些事情特别重要,所以我把所有事情都包括在内。)第 1 点和第 2 点已在上面描述,所以我不会详述它们。
我。我 re-installed unixODBC
和 freeTDS
来自他们的项目网站。
二.我发现我的 LAN 上的 1433 端口被阻止了,所以我切换到未被阻止的 WiFi。
这两件事让我能够让 isql
和 osql
工作。
三。由于类似于动态链接错误的原因,pyodbc
无法在 python 中导入。我尝试使用 dl.open()
和 ctype.cdll.LoadLibrary()
直接加载 /usr/local/lib/libodbc.dylib
。在这两种情况下,我都收到一条错误消息:
dl.error: dlopen(libodbc.dylib, 6): no suitable image found. Did find:
/usr/local/lib/libodbc.dylib: mach-o, but wrong architecture
经过一些挖掘,thie 引导我重新编译 unixODBC
32 位而不是 64 位 ,如下所示:
sudo ./configure CFLAGS="-m32 -arch i386 -O2" LDFLAGS="-m32 -arch i386" CXXFLAGS="-m32 -arch i386"
sudo make
sudo make install
那时,我可以使用 dl.open()
显式加载 libodbc.dylib
并且 最终 导入 pyodbc!!
四.不幸的是,没有通过 dl.open()
显式加载,导入仍然失败。这让我尝试使用我的 LD_LIBRARY_PATH
(建议 here),但似乎还没有任何效果。所以我仍然坚持使用 dl.open()
hack。
此外,它仍然没有工作,当我尝试连接到数据源时失败与 freeTDS
驱动程序有关。这最终让我想到了以下 "working" hack-around:
import sys
if (sys.platform == 'darwin'):
import dl
_lib1 = dl.open("libodbc.dylib") # Found in /usr/local/lib
_lib2 = dl.open("/opt/local/lib/libtdsodbc.so")
import pyodbc
请注意,必须使用全局变量 _lib1
和 _lib2
才能使其正常工作(我认为是为了保持内容加载)。
至此,一切似乎终于运行良好,我可以使用 pyodbc
!!
一路上我又尝试了一些东西,但我不清楚它们是否有帮助。
我也尝试在 32 位模式下编译
freeTDS
,类似于我为unixODBC
所做的,但我不确定是否有效。我从 github 存储库下载、构建并安装了
pyodbc
,而不是使用pip
。 (它与pip
提供的版本相同 -- 3.0.10。)根据评论 #10 here,我在
pyodbc
源下载(下方)中的setup.py
的darwin
案例中添加了两行和 re-ranpython.py setup.py build install
.
喜欢:
elif sys.platform == 'darwin':
# The latest versions of OS X no longer ship with iodbc. Assume
# unixODBC for now.
settings['libraries'].append('odbc')
settings['include_dirs'] = ['/opt/local/include'] # Added this line
settings['library_dirs'] = ['/opt/local/lib'] # Added this line
# Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot*
settings['extra_compile_args'].extend([
'-Wno-write-strings',
'-Wno-deprecated-declarations'
])
# Apple has decided they won't maintain the iODBC system in OS/X and has added deprecation warnings in 10.8.
# For now target 10.7 to eliminate the warnings.
settings['define_macros'].append( ('MAC_OS_X_VERSION_10_7',) )
settings['include_dirs'] = ['/opt/local/include']
settings['library_dirs'] = ['/opt/local/lib']
- 全部完成后,我进行了检查,我还能够导入和使用
pypyodbc
而无需 使用dl.open()
技巧。我不确定是否需要上述所有步骤才能实现。我怀疑主要问题是库的 32 位与 64 位版本。
最后,虽然这与我无法 pyodbc
导入的原因无关,但我会添加一条注释,说明导致我损失了将近一个小时的事情。在某些时候,我试图按照 this site. However, I later discovered that the non-DSN connection string that the author showed did not work. I instead had to use the FreeTDS connection attributes shown here 上的(非常有帮助的)说明进行操作。例如:
"DRIVER=FreeTDS;Server=*****;Port=1433;TDS_Version=7.2;Database=*****;UID=*****;PWD=*****"
虽然现在大部分情况下都对我有用,但我应该提一下,对于我的一些查询游标,我现在有时也会遇到以下错误,但我认为这与任何一个都无关以上。 (相反,我怀疑连接上存在某种 "timeout" 问题。...)
...
for row in cursor:
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1920, in next
row = self.fetchone()
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 1914, in fetchone
check_success(self, ret)
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 986, in check_success
ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
File "/Library/Python/2.7/site-packages/pypyodbc.py", line 966, in ctrl_err
raise DatabaseError(state,err_text)
pypyodbc.DatabaseError: (u'08S01', u'[08S01] [FreeTDS][SQL Server]Bad token from the server: Datastream processing out of sync')
Exception pypyodbc.DatabaseError: DatabaseError(u'08S01', u'[08S01] [FreeTDS][SQL Server]Write to the server failed') in <bound method Connection.__del__ of <pypyodbc.Connection instance at 0x60d5a8>> ignored
总而言之,我认为至少有 3 个(如果不是 4 个)我不能在 python 中使用 pyodbc
的原因。主要的两个与 unixODBC
的 32 位与 64 位编译和一些我仍然不太明白的库导入路径问题有关。
祝所有必须努力完成所有这些的人好运!
或者……
brew install unixodbc