尝试导入cx_Oracle时,我收到标准的“DLL加载失败;找不到模块”错误。我安装了正确的即时客户端,路径都正确...运行Dependency Walker告诉我我错过了以下.dll的 MSVCR90,GPSVC,IESHIMS。
我正在运行Oracle 11g和Python 2.7的即时客户端。有人有主意吗?我发现的大多数答案都会带来不正确的路径,但似乎并非如此......此外,我找不到任何其他的.dll在我的系统上的任何其他位置。
编辑: 我最终安装了Oracle XE 11g(32位); Python 2.7和cx_Oracle都是32位(我还应该添加我在Windows上)。 cx_Oracle现在安装得很干净;但是在连接时我收到一个错误:
InterfaceError: Unable to acquire Oracle environment handle
ORACLE_HOME路径是正确的,就像PATH文件夹中的bin一样......
答案 0 :(得分:8)
您运行的是哪个版本的Windows?是32位还是64位?
您的Oracle Instant Client 32或64位?
MSVCR90.dll是Microsoft Visual C ++ 2008 SP1可再发行组件包的一部分。
IESHIMS.dll将位于C:\Program Files\Internet Explorer\Ieshims.dll
(32位Windows位置或64位Windows位置)或C:\ Program Files \ Internet Explorer(x86)\ Ieshims.dll`(64位32位Windows位置)如果您的Windows版本是Vista或更新版本,请点击Windows)。
GPSVC.dll应该位于C:\Windows\System32
。
Dependency Walker将最后2个DLL报告为丢失,因为Windows错误报告使用了IEFrame.DLL并且延迟加载,这意味着它们可能永远不会被需要。
我发现为了让cx_oracle干净地导入,您需要确保其依赖项的版本匹配。您还需要确保Oracle客户端安装与您的ORACLE_HOME
匹配,并且您的PATH变量包含%ORACLE_HOME%/bin
,它被设置为环境变量或在注册表中,并且您的tnsnames.ora文件位于值TNS_ADMIN设置为。如 Emmanuel 的回答所述,未设置的TNS_ADMIN设置的默认值为%ORACLE_HOME%\network\admin
。
我也很少使用oracle安装程序的即时客户端版本,除非绝对必要,因为与其他版本不同,它总是确保设置或维护Path,ORACLE_HOME或TNS_ADMIN正确,这导致tnsnames.ora和OCI。 dll没被找到。如果在同一台机器上有多个Python版本或Oracle版本,这会变得更加复杂。
要显式设置它们,您可以使用环境变量(用户或系统),它们位于系统图标,高级系统设置任务,高级选项卡,环境按钮下的控制面板中。
关于InterfaceError: Unable to acquire Oracle environment handle
,这种情况发生在与不解析OCI.dll相反时,cx_Oracle不知道要使用哪个OCI.dll,通常是这种情况,因为PATH变量包含两个或多个搜索目录包含OCI.dll。
具体确保您的PATH仅包含来自即时客户端安装或Oracle 11G XE安装的OCI.dll的一个瞬间应该解决您的问题。
在安装Oracle 11G XE之前,您是否卸载了即时客户端?
将以下内容粘贴到命令提示符中。
echo The current ORACLE_HOME is %ORACLE_HOME%
echo The current TNS_ADMIN is %TNS_ADMIN%
echo The current PATH is %PATH%
查看这些变量的当前值。
更多资源
答案 1 :(得分:4)
我遇到了同样的问题:你必须设置变量ORACLE_HOME
以匹配你的Oracle客户端文件夹(在Unix上:例如通过shell;在Windows上:创建一个新变量,如果它不存在于配置面板的环境变量)因为这是cx_Oracle
模块可以链接到它的方式。
您的文件夹$ORACLE_HOME/network/admin
(Windows上为%ORACLE_HOME%\network\admin
)是您的tnsnames.ora
文件应存在的位置。
答案 2 :(得分:1)
我在案例中发现的是:
可重定位模式下的virtualenv设置( - 可定位)使用/usr/bin/env实用程序作为shebang用于django-admin.py:
#!/usr/bin/env python2.7
env是编写可以在各种 n x环境中运行的unix脚本的便捷工具
on OSX (我正在使用macos 10.12 Sierra)出于某种原因 / usr / bin / env隐藏了父进程中可见的一些系统变量 - 在此案例 DYLD_LIBRARY_PATH 未传输到子进程。测试:
set|grep DYLD_LIBRARY_PATH
DYLD_LIBRARY_PATH=.../oracle/instantclient_11_2
env|grep DYLD_LIBRARY_PATH
# nothing
再检查一下::
python -c "import os; print os.environ.get('DYLD_LIBRARY_PATH')"
.../instantclient_11_2:/usr/local/opt/openssl/lib
# put the same line in first line of django-admin.py
# and you will get no output for DYLD_LIBRARY_PATH
有趣的是,在Linux(例如CentOS)上并非如此,DYLD_LIBRARY_PATH和LD_LIBRARY_PATH在子进程中可见
因为这个cx_oracle.so无法加载所需的oracle库而失败并出现错误:
Unable to acquire Oracle environment handle
解决方案正在改变django-admin.py中的shebang:
从:
#!/usr/bin/env python2.7
之类的(检查你的python venv安装:哪个python):
#!.../venvs/project11/bin/python2.7
它的工作方式也是如此 - 但不像以前的解决方案那样灵活:
#!/usr/bin/env DYLD_LIBRARY_PATH=<put-full-path->/instantclient_11_2 python2.7
或最简单的在OSX中不使用可重定位的virtualenv设置
答案 3 :(得分:0)
我记得不得不搞乱这个很多来让它发挥作用。在运行Oracle XE的系统上的.bash_profile
中,我有:
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export SID=XE
export LD_LIBRARY_PATH=$ORACLE_HOME:$ORACLE_HOME/lib
export PATH=$PATH:$ORACLE_HOME/bin