在MacOSX上导入cx_Oracle(Python)

0 投票
2 回答
4053 浏览
提问于 2025-04-17 06:28

在一个Python脚本中导入cx_Oracle失败了。

我已经安装了cx_Oracle,使用的是“pip install cx_oracle” - 这个过程很顺利,显示已经安装好了。

现在当我尝试:

import cx_Oracle

我遇到了以下错误

Traceback (most recent call last):
  File "reader.py", line 9, in <module>
    import cx_Oracle
ImportError: dlopen(/Library/Python/2.7/site-packages/cx_Oracle.so, 2): Symbol not found: _OCIAttrGet
  Referenced from: /Library/Python/2.7/site-packages/cx_Oracle.so
  Expected in: flat namespace
 in /Library/Python/2.7/site-packages/cx_Oracle.so

其他信息:

Python版本 2.7 / mac os 10.7.2 (Lion)

$ python
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin    
Type "help", "copyright", "credits" or "license" for more information.

Oracle 10.2

$ sqlplus -version    
SQL*Plus: Release 10.2.0.4.0 - Production

另外,我的ORACLE_HOME文件夹里根本没有/bin目录,我只安装了即时客户端和SDK。

ox_Oracle

$ pip freeze
PyRSS2Gen==1.0.0
...
cx-Oracle==5.1.1

(我发现很多关于如何安装cx_Oracle的问题,但没有人问过这个 - 谢谢)

2 个回答

-1

先把所有东西都卸载掉。

然后安装Oracle即时客户端:

接着用pip来安装cx_oracle。

然后设置路径,让它指向Oracle的32位版本。

  • 在你的主目录中编辑.profile文件,添加Oracle的bin目录路径,使用这行代码:
  • export PATH=$PATH:/usr/local/lib/instantclient/

这样就可以用了……

2

今天我遇到了一个问题,通过把InstantClient二进制文件中引用的库的路径改成实际的文件系统位置,我解决了这个问题。这个博客 http://blog.caseylucas.com/2013/03/03/oracle-sqlplus-and-instant-client-on-mac-osx-without-dyld_library_path/ 提供了详细的解释和调整所有二进制文件的脚本。唯一的问题是,它使用了@executable_path,但在Python 2.7和El Capitan上似乎不再有效(我不太确定是什么导致了这个安全异常)。把@executable_path替换成实际路径就可以正常工作了。

总结一下,让它正常工作的步骤:

  • 把InstantClient安装到 /usr/local/instantclient_11_2
  • 确保你使用的cx_Oracle.so共享对象在 /Library/Python/2.7/site-packages/cx_Oracle.so 这个位置
  • 把下面的脚本复制到 /usr/local/instantclient_11_2

    #!/bin/sh
    # script to change the dynamic lib paths and ids for oracle instant client
    # exes and libs
    (echo /Library/Python/2.7/site-packages/cx_Oracle.so ; find . -maxdepth 1 -type f \( -perm -1 -o \( -perm -10 -o -perm -100 \) \) -print ) | while read exe
    do
        echo adjusting executable $exe
        baseexe=`basename $exe`
        otool -L $exe | awk '/oracle/ {print $1}' | while read lib
        do
            echo adjusting lib $lib
            baselib=`basename $lib`
            if [ "$baseexe" = "$baselib" ]
            then
                echo changing id to $baselib for $exe
                install_name_tool -id $baselib $exe
            else
                echo changing path id for $lib in $exe
                install_name_tool -change $lib /usr/local/instantclient_11_2/$baselib $exe
            fi
        done
    done
    
    • 用管理员权限运行这个脚本。

撰写回答