InterfaceError:无法获取Oracle环境句柄; ORACLE_HOME是正确的,SQL * Plus将连接

时间:2012-11-27 17:26:10

标签: python oracle cx-oracle

尝试导入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一样......

4 个答案:

答案 0 :(得分:8)

您运行的是哪个版本的Windows?是32位还是64位?

您的Oracle Instant Client 3264位?

您的Python安装是32还是64位?

你的cx_oracle是正确的版本吗? 3264位?

MSVCR90.dll是Microsoft Visual C ++ 2008 SP1可再发行组件包的一部分。

32位版本可用here,64位版本可用here

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
    
  • 使用cx_Oracle或任何其他DYLD_LIBRARY_PATH相关模块时,
  • 或最简单的在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