代码之家  ›  专栏  ›  技术社区  ›  Makoto

如何跟踪cx_oracle如何尝试连接到数据库?

  •  -1
  • Makoto  · 技术社区  · 6 年前

    我有三个python anaconda环境,其中安装了cx_oracle和oracle的instantclient。我在用 conda 为了提供虚拟环境,看起来运行良好,我使用oracle wallet向系统提供实际凭据。注意,这些环境没有也永远不会安装sql*plus,因为它们只是通过更高的抽象(例如python或java)与数据库通信。

    我遇到的麻烦来自三种环境中的两种。在执行以下python脚本时,连接仅在三个环境中的一个环境中工作正常。请注意,标识符在不同的环境中是不同的,但基本上是相同的。

    import cx_Oracle
    import os
    os.environ['TNS_ADMIN'] = '/data/config/wallets/app'
    conn = cx_Oracle.connect('/@ENV_CONNECTION')
    

    当我在一个环境中这样做时,我得到了一个和我期望的一样的游标实例,一切都正常。在另外两个上面,我看到:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    cx_Oracle.DatabaseError: ORA-12162: TNS:net service name is incorrectly specified
    

    我有 五倍检查 服务名称和钱包本身。有一个Java应用程序也在使用这个钱包,如果钱包被认为是坏的,它将无法连接,所以我原则上排除了这个可能性。

    唯一剩下的未知是钱包本身是如何被引用的。

    我如何反思cx_oracle是如何引用我的tns_管理位置并拉入正确的目录的?我觉得如果我能搞清楚,我就能解决剩下的问题。

    我的环境:

    • 条件4.4.11
    • 瞬间客户端12.2
    • CX_Oracle版本6.3.1
    2 回复  |  直到 6 年前
        1
  •  1
  •   Christopher Jones    6 年前
    • 检查cx_oracle传递给较低层(如oracle net)的内容的最简单方法可能是扩展连接类并添加自己的日志记录。基类是 cx_Oracle.Connection ,请参见示例 https://github.com/oracle/python-cx_Oracle/blob/master/samples/Subclassing.py

    • 您可以运行strace或类似程序来查看正在打开哪些Oracle配置文件,如tnsnames.ora。

    • 可以启用Oracle网络跟踪,请参见 ADR Diagnostic Parameters in sqlnet.ora 是的。对于简单的跟踪,我通常创建一个文件“~/.sqlnet.ora”,其内容如下: TRACE_LEVEL_CLIENT = USER ADR_BASE=/tmp 然后运行这个应用程序,在创建的 /tmp/oradiag_* 目录到 *.trc 文件夹。

        2
  •  0
  •   Makoto    6 年前

    克里斯托弗·琼斯的回答使我得到了救赎,但事实是,问题远比这更微妙。

    我最终创造了 sqlnet.ora 两台机器主目录中的文件-一台工作,另一台不工作。我注意到日志文件中有一个显著的差异。

    “好”框中有以下条目:

    2018-07-06 09:59:36.726 : nnftrne:Using tnsnames.ora address (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = my.oracle.db.host)(PORT = 1521)) (CONNECT_DATA = (SID = my_sid))) for name ENV_CONNECTION
    

    “坏”框中有以下条目:

    2018-07-06 10:02:12.879 : nnftrne:Using tnsnames.ora address (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = my.oracle.db.host)(PORT = 1521 for name ENV_CONNECTION
    

    这是我遇到过的最愚蠢和最令人惊讶的空白限制之一。

    请记住,正在使用的钱包(连同相应的tnsnames.ora文件)也在java中使用。我的假设是,当从这个共享资源中读取时,python和java的行为将相似,因为它们将在必要时忽略换行符和空白。

    我显然错了。

    “好”框中有如下条目:

    ENV_CONNECTION =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = my.oracle.db.host)(PORT = 1521))
        (CONNECT_DATA =
          (SID = my_sid)
        )
      )
    

    “坏”框中的条目如下所示:

    ENV_CONNECTION =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = my.oracle.db.host)(PORT = 1521
      ))
        (CONNECT_DATA =
          (SID = my_sid)
        )
      )
    

    这种差别非常微妙,但对python来说显而易见:如果tnsnames.ora文件的格式不正确,cx_oracle将 失败 去解析它,而java是 好的 带着这个。

    这感觉就像是一个错误本身,但是修复格式化允许Python再次连接。