我有一个看起来像这样的连接字符串
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
文件进行更改并不理想。此外,当我使用服务名称时,我根本不需要触摸此文件,并希望它保持这种状态。
答案 0 :(得分:43)
我是一个类似的场景,我可以使用cx_Oracle.makedsn()
创建一个带有给定SID
的 dsn 字符串(而不是服务名称)来连接到数据库:
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()
答案 1 :(得分:0)
它仍然可能无效。您需要获取dsnStr的输出并通过将SID替换为SERVICE_NAME来修改字符串,并在con字符串中使用该变量。这个程序对我有用。
答案 2 :(得分:0)
如果您使用的是sqlalchemy和ORACLE 12,则以下内容似乎有效。
from sqlalchemy import create_engine
con='oracle://user:password@hostname:1521/?service_name=DDDD'
engine = create_engine(con)
注意,您必须使用服务名称而不是SID。我不知道为什么,但使用SID的简单连接字符串不起作用。
答案 3 :(得分:0)
可能无法轻松访问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)))")
答案 4 :(得分:0)
我想过一段时间,由于连接中的服务名称问题,我将无法使用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@'
答案 5 :(得分:-1)
我也遇到过这个问题。 解决方案是:
1: get the service name at tnsnames.ora
2: put the service name in
con_str = "myuser/mypass@oracle.sub.example.com:1521/ora1"