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

时间:2014-06-10 19:14:34

标签: python oracle python-2.7 cx-oracle

我有一个看起来像这样的连接字符串

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文件进行更改并不理想。此外,当我使用服务名称时,我根本不需要触摸此文件,并希望它保持这种状态。

6 个答案:

答案 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"