Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a connection string that looks like this

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

Where ora1 is the SID of my database. Using this information in SQL Developer works fine, meaning that I can connect and query without problems.

However, if I attempt to connect to Oracle using this string, it fails.

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

This connection string format works if the ora1 is a service name, though.

I have seen other questions that seem to have the reverse of my problem (it works with SID, but not Service name)

  • Using Oracle Service Names with SQLAlachemy
  • Oracle SID and Service name; connection problems
  • cx_Oracle & Connecting to Oracle DB Remotely

What is the proper way to connect to Oracle, using cx_Oracle, using an SID and not a service name? How do I do this without the need to adjust the TNSNAMES.ORA file? My application is distributed to many users internally and making changes to the TNSNAMES file is less than ideal when dealing with users without administrator privileges on their Windows machines. Additionally, when I use service name, I don't need to touch this file at all and would like it keep it that way.

like image 945
Andy Avatar asked Jun 10 '14 19:06

Andy


People also ask

What is service name in Oracle connection string?

SERVICE_NAMES specifies one or more names by which clients can connect to the instance. The instance registers its service names with the listener. When a client requests a service, the listener determines which instances offer the requested service and routes the client to the appropriate instance.

How do I find the Oracle SID and service name?

select instance_name from v$instance; will give you SID name. select name from v$database; will give DB NAME. select instance_name from v$instance; will give you SID name.


2 Answers

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() 
like image 138
Andreas Fester Avatar answered Sep 29 '22 11:09

Andreas Fester


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) 
like image 31
Piotr Dobrogost Avatar answered Sep 29 '22 09:09

Piotr Dobrogost