在连接字符串上使用SID而不是服务名时,cx_Oracle不连接

2024-10-02 18:25:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个这样的连接字符串

con_str = "myuser/mypass@oracle.sub.example.com: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一起工作,但与服务名无关)

使用cx_Oracle、使用SID而不是服务名连接到Oracle的正确方法是什么?如何在不需要调整TNSNAMES.ORA文件的情况下执行此操作?我的应用程序在内部分发给许多用户,在处理没有Windows计算机管理员权限的用户时,对TNSNAMES文件进行更改并不理想。另外,当我使用服务名时,我根本不需要接触这个文件,希望它保持这种方式。


Tags: 文件字符串用户connectserviceconoraclecx
3条回答

对于那些寻找如何指定服务名而不是SID的用户。

来自changelog的SQLAlchemy 1.0.0b1(2015年3月13日发布):

[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.

更改引入了新的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)

在类似的场景中,我可以通过使用^{}创建一个带有给定SID(而不是服务名)的dsnstring来连接到数据库:

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

然后可以与^{}一起使用以连接到数据库:

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

如果您使用的是sqlalchemy和ORACLE 12,那么下面的代码似乎可以工作。

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

注意,必须使用服务名而不是SID。我不知道为什么,但是使用SID的简单连接字符串不起作用。

相关问题 更多 >