• sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的 SID


    主要原因可能是目标数据库是集群部署,可以咨询一下DBA

    python 用sqlalchemy 连接Oracle数据库的时候报了下面这个错误:

    sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的 SID
    (Background on this error at: http://sqlalche.me/e/4xp6)

    这是因为 sqlalchemy 在create_engine的时候默认是调用cx_Oracle去连接数据库,而cx_Oracle 在创建dns连接字符串的时候是默认SID = tnsname (实例名),其实是在连接的时候调用了 cx_Oracle.makedns 来构造连接url,我们通过下面的例子来看

    In[95]: import cx_Oracle
    In[96]: cx_Oracle.makedsn('10.24.04.19', '1314', 'report')
    Out[96]: '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.24.04.19)(PORT=1314))(CONNECT_DATA=(SID=report)))'
    In[97]: cx_Oracle.makedsn('10.24.04.19', '1314', service_name='report')
    Out[97]: '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.24.04.19)(PORT=1314))(CONNECT_DATA=(SERVICE_NAME=report)))'

      因为cx_Oracle不会去读我们配置的tnsname.ora文件,而是通过传进去的参数来构造连接url
    所以如果不指定service_name,那么这个函数就会默认将 ‘report’ 视为 SID (positional args),这样做的话对于单机部署的 Oracle数据库是没有问题的,但是如果目标数据库是集群部署的话,就会出现ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的 SID 的情况。
    更深入的解释可以看下面
      由于oracle 是做的多节点,然后有一个公用的service_name,只有通过service_name去连接才能起到负载均衡的作用,而以cx_Oracle默认的连接串去连的话只能连接到实例名,而不能连接到service_name,所以oracle用service_name去匹配实例名,当然找不到。所以连接时必须指定连的是service_name而不是sid.


    所以我们需要修改连接字符串,SQLAlchemy 连接方式:

    import cx_Oracle
    from sqlalchemy import create_engine
    ip = '10.24.04.19'
    port = '1314'
    uname = 'jiajia' # 用户名
    pwd = 'yupeng' # 密码
    tnsname = 'report' # 实例名
    
    dsnStr = cx_Oracle.makedsn(ip, port, service_name=tnsname)
    connect_str = "oracle://%s:%s@%s" %(uname, pwd, dsnStr)
    engine = create_engine(connect_str, encoding=encoding)

    cx_Oracle连接方法:

    conn = cx_Oracle.connect(uname, pwd, dsn=dsnStr)



  • 相关阅读:
    JavaScript之面向对象与原型笔记整理--------创建对象(1)
    PTA乙级 (*1030 完美数列 (25分))
    PAT乙级 (1033 旧键盘打字 (20分)(字母大小写转换、判断是否为大小写字母数字))
    PTA乙级 (*1040 有几个PAT (25分))
    PTA乙级 (1042 字符统计 (20分))
    PTA乙级 (1043 输出PATest (20分))
    PTA乙级 (1048 数字加密 (20分))
    PTA乙级 (1049 数列的片段和 (20分))
    PTA乙级 (1051 复数乘法 (15分))
    PTA乙级 (*1054 求平均值 (20分))
  • 原文地址:https://www.cnblogs.com/wynlfd/p/11053550.html
Copyright © 2020-2023  润新知