Ответ Кристофера Джонса привел меня к спасению, но реальность такова, что проблема была гораздо более тонкой, чем эта.
Я создал файлы 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 снова подключаться.