Как я могу проследить, как cx_Oracle пытается подключиться к базе данных? - PullRequest
0 голосов
/ 04 июля 2018

У меня есть три среды 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_ADMIN и извлекает нужный каталог? Я чувствую, что если я смогу понять это, я смогу решить все остальное.

Что у меня есть для моей среды:

  • Конда 4.4.11
  • InstantClient 12,2
  • cx_Oracle версия 6.3.1

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Ответ Кристофера Джонса привел меня к спасению, но реальность такова, что проблема была гораздо более тонкой, чем эта.

Я создал файлы 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 снова подключаться.

0 голосов
/ 04 июля 2018
  • Самый простой способ проверить, что cx_Oracle передает на нижние уровни (например, Oracle Net), может заключаться в расширении класса Connection и добавлении собственной регистрации. Базовый класс cx_Oracle.Connection, см. Пример https://github.com/oracle/python-cx_Oracle/blob/master/samples/Subclassing.py

  • Вы можете запустить strace или аналогичный, чтобы увидеть, какие файлы конфигурации Oracle, такие как tnsnames.ora, открываются.

  • Можно включить трассировку Oracle Net, см. Параметры диагностики ADR в sqlnet.ora . Для простой трассировки я обычно создаю файл "~ / .sqlnet.ora" с таким содержимым, как: TRACE_LEVEL_CLIENT = USER ADR_BASE=/tmp Затем запустите приложение и найдите в каталоге /tmp/oradiag_* файлы *.trc.

...