我无法在Macbook Pro(运行Mac OS X 10.10.5)和python版本2.7.10上导入pyodbc
。我用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
。
其中一个奇怪的事情是,我尝试使用的其他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
我怀疑&#34; Cellar&#34;部分,所以我看了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错误配置了一些内容。不幸的是,我很抱歉,我不知道/记得我采取了这样做的方式 - 我已经认真地尝试了几周与之相关的各种事情。
在毛罗的评论之后的第二次更新。
我取得了一些进展。我重新安装了unixODBC和freeTDS(直接来自http://www.unixodbc.org/和http://www.freetds.org/而不是使用自制程序),并且在这样做后,我的odbc_config
命令的输出与mauro的输出相匹配。
在玩了一些路径后,我能够同时获得osql
和isql
以成功连接到我的SQL Server实例。 (我发现之前失败的原因之一是因为我的组织中的IT部门在局域网上阻止了到端口1433的所有流量。当我切换到Wifi时,就像我的Windows同事一样,它起作用了。)我认为这个进步很大!
然而,当我尝试再次从python中导入pyodbc时,我得到了与我开始时完全相同的错误消息。叹。所以任何其他想法仍然会受到赞赏!
答案 0 :(得分:3)
我同意......在我看来,首先要检查的是底层的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
返回未找到的_SQLAllocHandle符号。这意味着它找不到合适的lib otool -L ...pyodbc.so
(与2.中的路径相同的路径)指向右侧的lib 如果是这种情况,我会重新安装pyodbc(我确实使用了pip
)。我听说旧版本有问题找到合适的标题/库。既然isql
有效...... pyodbc也可以正常工作。
答案 1 :(得分:3)
首先,感谢 @mauro 提供有用且持久的建议。
经过几个月的撞击墙壁,昨晚我终于能够开始工作了!
在这里,我概述了一些关键的事情(对我而言),希望这些事情可能对处于同样困境的其他人有用。
BG。不久前(一个多月),我阅读并试图做一些建议的事情here。虽然我不清楚地记得我尝过的每一件事,但这导致我tsql
正在工作,而且我认为,我安装了unixODBC
和freeTDS
的Homebrew版本。
从我提出上述问题开始,以下是我尝试的一些似乎产生影响的事情。 (我不确定哪些东西是最重要的,所以我一直都是如此。)上面描述的是第1点和第2点,所以我不会痴迷于它们。
予。我从他们的项目网站重新安装了unixODBC
和freeTDS
。
II。我发现端口1433在我的局域网上被阻塞了,所以我切换到WiFi,但它没有被阻止。
这两件事使我能够isql
和osql
工作。
III。由于类似于动态链接错误的原因导致pyodbc
无法在python中导入的推理。我尝试使用/usr/local/lib/libodbc.dylib
和dl.open()
直接加载ctype.cdll.LoadLibrary()
。在这两种情况下,我都告诉我错误:
dl.error: dlopen(libodbc.dylib, 6): no suitable image found. Did find:
/usr/local/lib/libodbc.dylib: mach-o, but wrong architecture
经过一番挖掘后,他引导我重新编译unixODBC
32-而不是64位,如下所示:
sudo ./configure CFLAGS="-m32 -arch i386 -O2" LDFLAGS="-m32 -arch i386" CXXFLAGS="-m32 -arch i386"
sudo make
sudo make install
此时,我能够使用libodbc.dylib
显式加载dl.open()
,最后 获取pyodbc导入!!
IV。遗憾的是,如果没有通过dl.open()
显式加载,导入仍然失败。这导致我玩LD_LIBRARY_PATH
(如建议的here),但似乎没有任何效果。所以我仍然坚持使用dl.open()
黑客。
此外,当我尝试连接数据源时,它仍然无法正常工作,与freeTDS
驱动程序无关。这最终促使我进入以下领域&#34;工作&#34;劈周围:
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 repo下载,构建并安装了pyodbc
,而不是使用pip
。 (它是相同的版本 - 3.0.10 - 尽管pip
供应。)
根据评论#10 here,我在darwin
源代码下载(下方)的setup.py
pyodbc
案例中添加了两行并重新运行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处的(非常有用的)指示。但是,我后来发现作者显示的非DSN连接字符串不起作用。我不得不使用FreeTDS连接属性shown here来使事情发挥作用。例如:
"DRIVER=FreeTDS;Server=*****;Port=1433;TDS_Version=7.2;Database=*****;UID=*****;PWD=*****"
虽然现在大部分内容都在为我工作,但我应该提一下,我现在有时也会出现以下错误,对于我的一些查询游标,但我不会认为它是&#39 ; s与上述任何相关。 (相反,我怀疑某种&#34;超时&#34;连接问题......)
...
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位编译以及我仍然不太了解的一些图书馆导入路径问题有关。
祝所有人不得不搞砸这一切,祝你好运!