cx_Oracle doesn't connect when using SID instead of service name on connection string

折月煮酒 提交于 2019-11-28 18:15:10

I a similar scenario, I was able to connect to the database by using cx_Oracle.makedsn() to create a dsn string with a given SID (instead of the service name):

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

This returns something like

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

which can then be used with cx_Oracle.connect() to connect to the database:

con = cx_Oracle.connect(user="myuser", password="mypass", dsn=dsnStr)
print con.version
con.close()

For those looking for how to specify service_name instead of SID.

From changelog for SQLAlchemy 1.0.0b1 (released on March 13, 2015):

[oracle] [feature] Added support for cx_oracle connections to a specific service name, as opposed to a tns name, by passing ?service_name=<name> to the URL. Pull request courtesy Sławomir Ehlert.

The change introduces new, Oracle dialect specific option service_name which can be used to build connect string like this:

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)
Mr. Mundkowsky

If you are using sqlalchemy and ORACLE 12, the following seems to work.

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

Note, you have to use the service name and not the SID. I don't know why, but the simple connection string that uses SID does not work.

It still may not work. You need to take the output of dsnStr and modify the string by replacing SID with SERVICE_NAME and use that variable in the con string. This procedure worked for me.

SID's may not be easily accessible or you might not have it created for your database.

In my case, I'm working from the client side requesting access to a cloud database so creating an SID didn't really make sense.

Instead, you might have a string that looks similar to this:

"(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)))"

You can use it in replacement of the 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)))")
daniel

I also met this issue. The solution is:

1: get the service name at tnsnames.ora
2: put the service name in
con_str = "myuser/mypass@oracle.sub.example.com:1521/ora1"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!