【问题标题】:InterfaceError: Unable to acquire Oracle environment handle; ORACLE_HOME is correct and SQL*Plus will connectInterfaceError:无法获取Oracle环境句柄; ORACLE_HOME 正确,SQL*Plus 将连接
【发布时间】:2020-10-06 15:52:11
【问题描述】:

我在尝试导入 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 也正确...

【问题讨论】:

    标签: python oracle cx-oracle


    【解决方案1】:

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

    您的 Oracle Instant Client 3264 是位吗?

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

    您的 cx_oracle 版本是否正确? 3264 位?

    MSVCR90.dll 是 Microsoft Visual C++ 2008 SP1 Redistributable 包的一部分。

    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 位 Windows 上的 32 位 Windows 位置) ) ,如果您的 Windows 版本是 Vista 或更高版本。

    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 安装程序的即时客户端版本,除非绝对必要,因为与其他版本不同,它并不总是确保正确设置或维护路径、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%

    查看这些变量的当前值。

    更多资源

    【讨论】:

    • 我的 ORACLE_HOME 如下:Oracle\app\oracle\product\11.2.0\server,应该是这样,路径是正确的 bin 文件夹......我现在得到“无法获取 oracle 环境句柄”...(请参阅对主要问题的编辑)...此外,我可以连接 SQL Plus。
    【解决方案2】:

    我遇到了同样的问题:您必须设置变量 ORACLE_HOME 以匹配您的 Oracle 客户端文件夹(在 Unix 上:例如通过 shell;在 Windows 上:如果环境中不存在新变量,则创建一个新变量配置面板的变量),因为这是 cx_Oracle 模块可以链接到它的方式。

    您的文件夹$ORACLE_HOME/network/admin(Windows 上为%ORACLE_HOME%\network\admin)是您的tnsnames.ora 文件应该存在的位置。

    【讨论】:

    • 我的 ORACLE_HOME 与我的 Oracle 客户端文件夹匹配,但仍然出现相同的错误,我的 tnsnames.ora 也位于正确的位置。有什么想法吗?
    【解决方案3】:

    更新 06.10.2020

    好像MacOS DYLD_LIBRARY_PATH unset for security reasons:

    生成受系统限制的进程的子进程 完整性保护,例如通过在 与 NSTask 捆绑或调用 exec(2) 命令,重置 Mach 该子进程的特殊端口。任何动态链接器 (dyld) 环境变量,例如 DYLD_LIBRARY_PATH,在 启动受保护的进程。

    几种可能的解决方案:

    • 将脚本中的 shebang 行从 env(例如 #!/usr/bin/env python2.7)替换为 python (#!.../venvs/project11/bin/python2.7),稍后解释
    • 在调用python脚本的脚本中设置DYLD_LIBRARY_PATH
    • 这样调用脚本:DYLD_LIBRARY_PATH=... <script-to-run>
    • 在 shell (.bash_profile 或类似) 中设置 DYLD_LIBRARY_PATH 并使用 source/. <script-to-run> 调用您的脚本

    老分析

    我的发现如下:

    • 可重定位模式下的virtualenv设置(--relocatable)使用/usr/bin/env实用程序作为django-admin.py的shebang

      #!/usr/bin/env python2.7
      
    • env 是编写可在各种 nx 环境中运行的 unix 脚本的便捷实用程序

    • 在 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 设置

    【讨论】:

      【解决方案4】:

      我记得我不得不很多弄乱它才能让它工作。在运行 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
      

      【讨论】:

        【解决方案5】:

        也许你可以将所有带有'.dll'扩展名的文件复制到Python的安装路径中,比如'%python_home%\Lib\site-packages'。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-08
          • 1970-01-01
          • 2017-08-17
          • 1970-01-01
          • 1970-01-01
          • 2018-06-08
          • 2010-11-12
          • 1970-01-01
          相关资源
          最近更新 更多