как исправить cx_ Oracle .DatabaseError: ORA-12170: TNS: истекло время ожидания подключения - PullRequest
0 голосов
/ 20 июня 2020

Я пытаюсь запустить сценарий Python для вставки некоторых данных в таблицу Oracle из изображения docker.

Мне дали следующую строку подключения:

jdbc:oracle:thin:@(DESCRIPTION=(CONNECT_TIMEOUT=3)(RETRY_COUNT=2)(FAILOVER=ON)(LOAD_BALANCE=NO) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_1)(PORT=1521))) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))   

Я пытаюсь подключиться, используя cx_Oracle package:

try:
    # establish a new connection
    with cx_Oracle.connect(self.oracle_user,
                            self.oracle_pwd,
                            self.oracle_dsn) as connection:
        logger.info('ElasticsearchFinder.oracle_write : connexion established with DB')

, где oracle_dsn является строкой подключения (без части jdbc:oracle:thin:@)

Я тоже пробовал например,

cx_Oracle.connect(self.oracle_user+'/'+self.oracle_pwd+'@'+self.oracle_dsn)

, как показано в некоторых примерах, но я всегда получаю следующую ошибку тайм-аута:

cx_Oracle.DatabaseError: ORA-12170: TNS:Connect timeout occurred

telnet host 1521 работает нормально, я также пытался изменить значение CONNECT_TIMEOUT.

Я также пробовал

dsn_tns = cx_Oracle.makedsn(self.oracle_host, self.oracle_port, service_name = self.oracle_service_name)
cx_Oracle.connect(self.oracle_user,self.oracle_pwd,dsn_tns) 

как было предложено здесь , но потом я получаю

cx_Oracle.DatabaseError: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

Я запускаю свой скрипт из Docker сборка образа с помощью Dockerfile:

FROM oraclelinux:7.8
RUN  yum -y install oracle-release-el7 && \
     yum-config-manager --enable ol7_oracle_instantclient && \
     yum -y install oracle-instantclient18.3-basic && \
     rm -rf /var/cache/yum
COPY ./fetch_session_iptv.py /opt/
COPY ./conf/fetch_session_iptv.conf /opt/conf/
#COPY ./conf/certs/* /opt/conf/certs/
COPY ./logs /opt/logs
RUN yum install -y \
    #https://yum.oracle.com/repo/OracleLinux/OL7/developer/x86_64/getPackage/oracle-instantclient18.3-basic-18.3.0.0.0-2.x86_64.rpm \
    https://yum.oracle.com/repo/OracleLinux/OL7/developer/x86_64/getPackage/python-cx_Oracle-7.3-1.el7.x86_64.rpm \
    https://yum.oracle.com/repo/OracleLinux/OL7/developer/x86_64/getPackage/python36-pytz-2016.10-2.0.1.el7.noarch.rpm
COPY ./python_requirements/elasticsearch-7.8.0-py2.py3-none-any.whl .
COPY ./python_requirements/certifi-2020.4.5.2-py2.py3-none-any.whl .
COPY ./python_requirements/urllib3-1.25.9-py2.py3-none-any.whl .
RUN pip3 install --user \
    certifi-2020.4.5.2-py2.py3-none-any.whl \
    urllib3-1.25.9-py2.py3-none-any.whl \
    elasticsearch-7.8.0-py2.py3-none-any.whl \
    cx_Oracle
RUN sh -c "echo /usr/lib/oracle/18.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf"
RUN ldconfig
RUN export ORACLE_HOME=/usr/lib/oracle/18.3/client64/
RUN yum -y install telnet
#CMD ["/bin/bash"]
CMD [ "python3", "/opt/fetch_session_iptv.py" ]

Я не могу понять, что происходит не так?

[ UPDATE ] Я установил

  • ORACLE_HOME=/usr/lib/oracle/18.3/client64/bin
  • TNS_ADMIN=$ORACLE_HOME/admin
  • LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib
  • PATH=$PATH:$ORACLE_HOME

Я добавил файл tnsnames.ora в Каталог TNS_ADMIN с

CNX=(DESCRIPTION=(CONNECT_TIMEOUT=3)(RETRY_COUNT=2)(FAILOVER=ON)(LOAD_BALANCE=NO) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_1)(PORT=1521))) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))

Теперь, когда я пытаюсь sqlplus MY_USER@CNX, я получаю то же самое:

ORA-12170: TNS:Connect timeout occured

, но, по крайней мере, кажется, что он принимает строку подключения и пользователя. Перед тем, как правильно установить все переменные среды, у меня были только разные сообщения об ошибках TNS о неправильном имени службы TNS: listener does not currently know of service requested in connect descriptor или net.

[ UPDATE 2 ] Я проверил с человеком, который предоставил мне всю информацию о подключении: пользователь, пароль и строка подключения верны. У них запущена Oracle База данных 12 c (12.1.0.2.0), которая согласно эта страница совместима с клиентом 18 c, который я использую.

Я не знаю, что еще могло быть возможной причиной этой ошибки тайм-аута?

1 Ответ

0 голосов
/ 21 июня 2020

Начните с использования эквивалентной строки подключения в cx_ Oracle:

self.oracle_dsn = "(DESCRIPTION=(CONNECT_TIMEOUT=3)(RETRY_COUNT=2)(FAILOVER=ON)(LOAD_BALANCE=NO) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_1)(PORT=1521))) (ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))"

try:
    # establish a new connection
    with cx_Oracle.connect(self.oracle_user,
                            self.oracle_pwd,
                            self.oracle_dsn) as connection:
        logger.info('ElasticsearchFinder.oracle_write : connexion established with DB')

Руководство cx_ Oracle по соединению и соединению строк: здесь .

Лично я бы использовал 19 c Instant Client, который будет подключаться к тем же версиям БД, что и 18 c - и не требует запуска ldconfig. См. Docker для Oracle приложений баз данных в Node.js и Python.

Обновите свой вопрос информацией, и я могу обновить этот ответ аналогичным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...