Python 如何跟踪cx_Oracle试图连接到数据库的方式?
我有三个Python Anaconda环境,其中安装了cx_Oracle和Oracle的Instantclient。我正在使用Python 如何跟踪cx_Oracle试图连接到数据库的方式?,python,conda,cx-oracle,Python,Conda,Cx Oracle,我有三个Python Anaconda环境,其中安装了cx_Oracle和Oracle的Instantclient。我正在使用conda来提供虚拟环境,它似乎工作正常,我正在使用Oracle Wallet向系统提供实际凭证。请注意,这些环境没有也永远不会安装SQL*Plus,因为它们只是通过更高的抽象(例如Python或Java)与数据库通信 我遇到的麻烦来自三种环境中的两种。在执行以下Python脚本时,连接仅适用于三种环境中的一种。请注意,标识符在不同环境中是不同的,但大致相同 import
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
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
cx_Oracle.DatabaseError:ORA-12162:TNS:net服务名称指定不正确
我已经检查了服务名称和钱包本身。有一个Java应用程序也在使用这个钱包,如果钱包被认为是坏的,它将无法连接,所以我原则上排除这种可能性
唯一尚不清楚的是钱包本身是如何被引用的
我如何反思cx_Oracle是如何引用我的TNS_管理位置并将其放入正确的目录的?我觉得如果我能弄明白,我就能解决剩下的问题
我为我的环境所做的:
- 康达4.4.11
- instantclient 12.2
- cx_Oracle版本6.3.1
- 检查cx_Oracle传递给较低层(例如Oracle Net)的内容的最简单方法可能是扩展连接类并添加您自己的日志记录。基类是
,请参见示例cx\u Oracle.Connection
- 您可以运行strace或类似程序,查看正在打开哪些Oracle配置文件,如tnsnames.ora
- 可以启用Oracle Net跟踪,请参阅。对于一个简单的跟踪,我通常创建一个文件“~/.sqlnet.ora”,其内容如下:
然后运行应用程序,通过创建的跟踪\级别\客户端=用户 日均房价基数=/tmp
目录深入到/tmp/oradiag.*
文件*.trc
- 检查cx_Oracle传递给较低层(例如Oracle Net)的内容的最简单方法可能是扩展连接类并添加您自己的日志记录。基类是
,请参见示例cx\u Oracle.Connection
- 您可以运行strace或类似程序,查看正在打开哪些Oracle配置文件,如tnsnames.ora
- 可以启用Oracle Net跟踪,请参阅。对于一个简单的跟踪,我通常创建一个文件“~/.sqlnet.ora”,其内容如下:
然后运行应用程序,通过创建的跟踪\级别\客户端=用户 日均房价基数=/tmp
目录深入到/tmp/oradiag.*
文件*.trc
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
“坏”框中有以下条目:
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)
)
)
“坏”框中的条目如下所示:
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对此没有问题
这本身就是一个bug,但修复格式可以让Python再次连接。克里斯托弗·琼斯的回答让我找到了救赎,但现实是问题远比这微妙 最后,我在两台机器的主目录中创建了
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
“坏”框中有以下条目:
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)
)
)
“坏”框中的条目如下所示:
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再次连接。您也可以使用sqlplus使用提供给cx_Oracle的连接字符串连接到数据库。您也可以使用sqlplus使用提供给cx_Oracle的连接字符串连接到数据库。我想与Oracle开发团队跟进。你在哪个站台?什么JDBC版本?文件是否有*IX或Windows行终止?@Christophe