Python 甲骨文没有';在连接字符串上使用SID而不是服务名称时无法连接
我有一个像这样的连接字符串Python 甲骨文没有';在连接字符串上使用SID而不是服务名称时无法连接,python,oracle,python-2.7,cx-oracle,Python,Oracle,Python 2.7,Cx Oracle,我有一个像这样的连接字符串 con_str = "myuser/mypass@oracle.sub.example.com:1521/ora1" 其中ora1是我的数据库的SID。在SQLDeveloper中使用这些信息效果很好,这意味着我可以毫无问题地连接和查询 但是,如果我尝试使用此字符串连接到Oracle,它将失败 cx_Oracle.connect(con_str) DatabaseError: ORA-12514: TNS:listener does not curren
con_str = "myuser/mypass@oracle.sub.example.com:1521/ora1"
其中ora1
是我的数据库的SID。在SQLDeveloper中使用这些信息效果很好,这意味着我可以毫无问题地连接和查询
但是,如果我尝试使用此字符串连接到Oracle,它将失败
cx_Oracle.connect(con_str)
DatabaseError: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor
但是,如果ora1
是服务名称,则此连接字符串格式可以工作
我看到其他问题似乎与我的问题相反(它适用于SID,但不适用于服务名称)
使用
cx\u Oracle
、使用SID
而不是服务名称连接到Oracle的正确方式是什么?如何在不需要调整TNSNAMES.ORA
文件的情况下执行此操作?我的应用程序在内部分发给许多用户,在处理Windows计算机上没有管理员权限的用户时,对TNSNAMES
文件进行更改并不理想。另外,当我使用服务名时,我根本不需要接触这个文件,并且希望它保持这种方式 I在类似的场景中,我可以使用创建一个带有给定SID
(而不是服务名称)的dsn字符串来连接到数据库:
这返回类似于
(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()
它可能仍然不起作用。您需要获取dsnStr的输出并通过将SID替换为SERVICE_NAME来修改字符串,并在con字符串中使用该变量。这个过程对我很有效。我也遇到了这个问题。 解决办法是:
1: get the service name at tnsnames.ora
2: put the service name in
con_str = "myuser/mypass@oracle.sub.example.com:1521/ora1"
对于那些寻找如何指定服务名称而不是SID的用户 SQLAlchemy 1.0.0b1(于2015年3月13日发布)的源代码: [oracle][feature]添加了对cx_oracle连接到服务器的支持 与tns名称相反,通过传递
?服务名称=
到URL。拉取请求由Sławomir提供
埃勒特
此更改引入了新的Oracle方言特定选项服务\u 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)
如果您使用的是sqlalchemy和Oracle12,那么下面的代码似乎可以工作
from sqlalchemy import create_engine
con='oracle://user:password@hostname:1521/?service_name=DDDD'
engine = create_engine(con)
注意,您必须使用服务名称,而不是SID。我不知道为什么,但是使用SID的简单连接字符串不起作用。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)))")
有一段时间我认为我将无法使用Magic SQL(
%SQL
,%SQL
),因为连接中存在服务名称问题,这将强制使用上述cx_Oracle.connect(),cx_Oracle.makedsn()的替代方法…
我终于找到了一个适合我的解决方案:首先为服务名声明并设置一个变量,然后在命令中使用它(因为如果在命令中放入服务名的文本字符串,则该解决方案不起作用!)
输出(您在成功连接中获得的):
文件非常清楚。只需执行
cx_Oracle.makedsn(“Oracle.sub.example.com”,“1521”,service_name=“ora1”)
,显式使用关键字service_name
将其与第三个参数(即sid
)区分开来。非常有用,经过两天的搜索后,它在这里登陆,工作时间不到30秒。极好的非常感谢@Andreas Fester@S4nd33p谢谢,很高兴听到它有帮助:-)经过一个月的搜索,并使用不同类型的目录和环境变量,这是最终让我连接到服务器并开始提取数据的答案。非常好这是关于cx\u Oracle
而不是sqlalchemy
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)))")
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@'