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

У меня есть строка подключения, которая выглядит так

con_str = "myuser/[email protected]:1521/ora1"

Где ora1 - это SID моей базы данных. Использование этой информации в SQL Developer отлично работает, а это означает, что я могу без проблем подключаться и делать запросы.

Однако если я попытаюсь подключиться к Oracle с помощью этой строки, это не удастся.

cx_Oracle.connect(con_str)

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

Однако этот формат строки подключения работает, если ora1 - имя службы.

Я видел другие вопросы, которые, кажется, имеют обратную сторону моей проблемы (он работает с SID, но не с именем службы)

Как правильно подключиться к Oracle, используя cx_Oracle, используя SID, а не имя службы? Как мне это сделать, не изменяя файл TNSNAMES.ORA? Мое приложение распространяется среди многих пользователей внутри компании, и внесение изменений в файл TNSNAMES далеко не идеально при работе с пользователями без прав администратора на их машинах с Windows. Кроме того, когда я использую имя службы, мне вообще не нужно трогать этот файл, и я бы хотел, чтобы он оставался таким.


person Andy♦    schedule 10.06.2014    source источник


Ответы (7)


В аналогичном сценарии мне удалось подключиться к базе данных с помощью cx_Oracle.makedsn() для создания < strong> dsn с заданным SID (вместо имени службы):

dsnStr = cx_Oracle.makedsn("oracle.sub.example.com", "1521", "ora1")

Это возвращает что-то вроде

(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle.sub.example.com)(PORT=1521)))(CONNECT_DATA=(SID=ora1)))

который затем можно использовать с cx_Oracle.connect() для подключения к базе данных:

con = cx_Oracle.connect(user="myuser", password="mypass", dsn=dsnStr)
print con.version
con.close()
person Andreas Fester    schedule 22.09.2014
comment
Документация очень четкая. Просто выполните cx_Oracle.makedsn("oracle.sub.example.com", "1521", service_name="ora1"), явно используя ключевое слово service_name, чтобы отличить его от третьего аргумента (который равен sid). - person dmvianna; 02.12.2016
comment
Очень полезно, приземлился здесь через 2 дня поиска и работал менее чем за 30 секунд. Потрясающий. Большое спасибо @Andreas Fester. - person S4nd33p; 18.07.2017
comment
@ S4nd33p Спасибо, рад слышать, что это помогло :-) - person Andreas Fester; 18.07.2017
comment
После месяца поиска и экспериментов с различными типами каталогов и переменных среды, вот ответ: наконец, подключите меня к серверу и начните получать данные. Очень хорошо - person xappppp; 08.03.2019

Для тех, кто хочет узнать, как указать service_name вместо SID.

Из журнала изменений для SQLAlchemy 1.0.0b1 (выпущен 13 марта 2015 г.):

[oracle] [функция] Добавлена ​​поддержка подключений cx_oracle к определенному имени службы, в отличие от имени tns, путем передачи ?service_name=<name> в URL-адрес. Запрос на вытягивание любезно предоставлен Славомиром Элертом.

Это изменение вводит новую, специфичную для диалекта Oracle опцию service_name, которую можно использовать для построения строки подключения следующим образом:

from sqlalchemy import create_engine
from sqlalchemy.engine import url

connect_url = url.URL(
    'oracle+cx_oracle',
    username='some_username',
    password='some_password',
    host='some_host',
    port='some_port',
    query=dict(service_name='some_oracle_service_name'))

engine = create_engine(connect_url)
person Piotr Dobrogost    schedule 08.05.2017
comment
Это вопрос о cx_Oracle, а не о sqlalchemy - person Superdooperhero; 11.03.2021

Если вы используете sqlalchemy и ORACLE 12, похоже, работает следующее.

from sqlalchemy import create_engine
con='oracle://user:password@hostname:1521/?service_name=DDDD'
engine = create_engine(con)

Обратите внимание: вы должны использовать имя службы, а не SID. Я не знаю почему, но простая строка подключения, использующая SID, не работает.

person Mr. Mundkowsky    schedule 12.06.2017

Это все еще может не работать. Вам нужно взять вывод dsnStr и изменить строку, заменив SID на SERVICE_NAME и использовать эту переменную в строке con. Эта процедура у меня сработала.

person Srinivas Ganti    schedule 13.11.2015

Доступ к SID может быть затруднен, или он может быть не создан для вашей базы данных.

В моем случае я работаю на стороне клиента, запрашивая доступ к облачной базе данных, поэтому создание SID не имело смысла.

Вместо этого у вас может быть строка, которая выглядит примерно так:

"(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = something.cloud.company)
(PORT = 12345)) (ADDRESS = (PROTOCOL = TCP)(HOST = something.cloud.company)
(PORT = 12345)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = 
something.company)))"

Вы можете использовать его вместо SID.

connection = cx_Oracle.connect("username", "pw", "(DESCRIPTION = (ADDRESS = 
                (PROTOCOL = TCP)(HOST = something.cloud.company)(PORT = 12345)) (ADDRESS = 
                (PROTOCOL = TCP)(HOST = something.cloud.company)(PORT = 12345)) 
                (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = something.company)))")
person Daniel Holliday    schedule 27.07.2017

Некоторое время я думал, что не смогу использовать Magic SQL (%sql, %%sql) из-за проблемы с именем службы в соединении, которая вынудила бы использовать альтернативный способ, описанный выше, с cx_Oracle.connect (), cx_Oracle.makedsn()... Я наконец нашел решение работает для меня: сначала объявите и установите переменную для имени службы, а затем используйте ее в команде (поскольку не работает, если буквальная строка для имени службы помещена в команду!)

import cx_Oracle

user='youruser'
pwd='youruserpwd'
dbhost='xx.xx.xx.xx'
service='yourservice'

%load_ext sql
%sql oracle+cx_oracle://$user:$pwd@$dbhost:1521/?service_name=$service

вывод (что вы получите при успешном подключении):

u'Connected: youruser@'
person Christophe OGER    schedule 12.04.2020

Я тоже столкнулся с этой проблемой. Решение такое:

1: get the service name at tnsnames.ora
2: put the service name in
con_str = "myuser/[email protected]:1521/ora1"
person daniel    schedule 19.02.2016