conectar con 12c 10g python oracle python-2.7 cx-oracle

con - python oracle 12c



cx_Oracle no se conecta al usar SID en lugar del nombre del servicio en la cadena de conexión (6)

Tengo una cadena de conexión que se parece a esto

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

Donde ora1 es el SID de mi base de datos. Usar esta información en SQL Developer funciona bien, lo que significa que puedo conectarme y consultar sin problemas.

Sin embargo, si intento conectarme a Oracle utilizando esta cadena, falla.

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

Este formato de cadena de conexión funciona si el ora1 es un nombre de servicio, sin embargo.

He visto otras preguntas que parecen tener el reverso de mi problema (funciona con SID, pero no con el nombre de servicio)

  • Usar los nombres de servicio de Oracle con SQLAlachemy
  • Nombre de Oracle SID y servicio; problemas de conexión
  • cx_Oracle y conexión a Oracle DB de forma remota

¿Cuál es la forma correcta de conectarse a Oracle utilizando cx_Oracle , utilizando un SID y no un nombre de servicio? ¿Cómo hago esto sin la necesidad de ajustar el archivo TNSNAMES.ORA ? Mi aplicación se distribuye a muchos usuarios internamente y hacer cambios en el archivo TNSNAMES es menos que ideal cuando se trata de usuarios sin privilegios de administrador en sus máquinas con Windows. Además, cuando uso el nombre del servicio, no necesito tocar este archivo y me gustaría que lo mantuviera de esa manera.


En una situación similar, pude conectarme a la base de datos usando cx_Oracle.makedsn() para crear una cadena dsn con un SID dado (en lugar del nombre del servicio):

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

Esto devuelve algo así como

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

que luego se puede usar con cx_Oracle.makedsn() para conectarse a la base de datos:

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


Es posible que los SID no sean de fácil acceso o que no los haya creado para su base de datos.

En mi caso, estoy trabajando desde el lado del cliente solicitando acceso a una base de datos en la nube, por lo que crear un SID no tiene sentido.

En su lugar, es posible que tenga una cadena que se parece a esto:

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

Puede usarlo en reemplazo del 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)))")


Para aquellos que buscan cómo especificar service_name en lugar de SID.

Del changelog de changelog para SQLAlchemy 1.0.0b1 (lanzado el 13 de marzo de 2015):

[oracle] [feature] Se agregó soporte para conexiones de cx_oracle a un nombre de servicio específico, a diferencia de un nombre de tns, pasando ?service_name=<name> a la URL. Solicitud de extracción cortesía de Sławomir Ehlert.

El cambio introduce una nueva opción específica de dialecto de Oracle service_name que se puede usar para construir una cadena de conexión como esta:

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)


Si usa sqlalchemy y ORACLE 12, lo siguiente parece funcionar.

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

Tenga en cuenta que debe usar el nombre del servicio y no el SID. No sé por qué, pero la cadena de conexión simple que usa SID no funciona.


También conocí este problema. La solucion es:

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


Todavía puede no funcionar. Debe tomar el resultado de dsnStr y modificar la cadena reemplazando SID con SERVICE_NAME y usar esa variable en la cadena de conexión. Este procedimiento funcionó para mí.