【问题标题】:Unable to connect Python to Oracle无法将 Python 连接到 Oracle
【发布时间】:2019-10-23 19:04:40
【问题描述】:

我想使用 cx_Oracle 将 Python 连接到本地 Oracle。我知道为了建立连接,我应该知道本地 IP、端口和 SID。所以我通过以下步骤获取这些信息:

本地 IP:

import socket
#get local IP:
localhost = socket.gethostbyname(socket.gethostname())

端口: 这是来自我的 listener.ora,所以我使用端口 1521。

# listener.ora Network Configuration File: C:\app\413022472\product\12.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = C:\app\413022472\product\12.2.0\dbhome_1)
      (PROGRAM = extproc)
      (ENVS = "EXTPROC_DLLS=ONLY:C:\app\413022472\product\12.2.0\dbhome_1\bin\oraclr12.dll")
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-2RE9AJU.local)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

DEFAULT_SERVICE_LISTENER = (orcl)

sid:这让我很困扰。我尝试了很多,但仍然无法获得正确的 sid。这是来自我的 tnsnames.ora

# tnsnames.ora Network Configuration File: C:\app\413022472\product\12.2.0\dbhome_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools.

LISTENER_ORCL =
  (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-2RE9AJU.local)(PORT = 1521))


ORACLR_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
    (CONNECT_DATA =
      (SID = CLRExtProc)
      (PRESENTATION = RO)
    )
  )

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

这是我在sqlplus中运行select instance_name from v$instance;时得到的:

INSTANCE_NAME
--------------------------------
orcl

我尝试了以下方法:

import cx_Oracle
import socket
#get local IP:
localhost = socket.gethostbyname(socket.gethostname())
#generate dsn:
dsn = cx_Oracle.makedsn(localhost, '1521', service_name = 'orcl')
#make connection:
conn = cx_Oracle.connect("c##scott", "tiger", dsn) 

这给了我:DatabaseError:ORA-12514, TNS:listener does not currently know of service requested in connect descriptor

我也试过dsn = cx_Oracle.makedsn(localhost, '1521', sid = 'orcl') 这给了我:ORA-12505: TNS:listener does not currently know of SID given in connect descriptorD

我应该说我更改了 listener.ora 和 tnsnames.ora 中的文本,但我不记得细节了。谁能帮我连接成功?

【问题讨论】:

    标签: python oracle cx-oracle


    【解决方案1】:

    在侦听器中,有很多东西会影响创建连接。 以下是根据我的系统的“listener.ora”文件的内容。 在此之前,通过在命令提示符中使用“主机名”来验证您的主机名是否有效。在替换侦听器文件的内容之前,获取现有 listener.ora 文件的副本。一旦你修改了 listener.ora 文件,然后重新启动 listener 和 Oracle 服务。

    LISTENER =
      (DESCRIPTION_LIST =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) 
          (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-2RE9AJU.local)(PORT = 1521))
        )
      )
    
    
    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC =
          (SID_NAME = CLRExtProc)
          (ORACLE_HOME = C:\app\413022472\product\12.2.0\dbhome_1)
          (PROGRAM = extproc)
          (ENVS = "EXTPROC_DLLS=ONLY:C:\app\413022472\product\12.2.0\dbhome_1\bin\oraclr12.dll")
        )
       (SID_DESC = 
          (GLOBAL_DBNAME = orcl.com)
          (ORACLE_HOME =C:\app\413022472\product\12.2.0\dbhome_1)
          (SID_NAME = orcl)
        )
    
      )
    
    DEFAULT_SERVICE_LISTENER = (orcl)
    

    【讨论】:

    • 我终于做对了,但不知道究竟是什么影响了结果。也许重新启动服务。请告诉我为什么我的 tnsnames 中的 SID 是“CLRExtProc”,而我在 sqlplus 中找到的 SID 是“orcl”?有什么不同?我使用dsn = cx_Oracle.makedsn(#my_PC_name#, '1521', sid = 'orcl') 使连接成功。
    • @YQ.Wang,你可以在“SID_LIST”中看到有两个不同的“SID_DESC”,一个是你的jdbc/odbc/dsn连接,另一个是外部程序连接,连我都没用过.但无论如何,这不会打扰你。如果您喜欢我的回答,请接受答案。谢谢:)
    【解决方案2】:

    我会使用来自 Oracle tutorial 的 sn-p(记得相应地更改用户/密码)。

    import cx_Oracle
    con = cx_Oracle.connect('pythonhol/welcome@127.0.0.1/orcl')
    print con.version
    con.close()
    

    这是官方cx_Oracle Documentation的链接。

    最后,在this GitHub URL,您可以找到几个更新的示例,这些示例可能有助于加快您的工作。

    【讨论】:

    【解决方案3】:

    根据我的经验,这可能是一个非常令人沮丧的调试错误。您可能已经解决了这个错误,但我会在此处添加我的解决方案,供任何遇到通过 cx_Oracle 连接到 Oracle 的类似错误的人使用。

    这里需要注意的重点:

    1. 虽然是数据库错误,但是杀掉并重启数据库监听的服务是解决不了的,这和我们通过cx_连接的关系有关
    2. 确保 Oracle 客户端和 Python 具有相同的体系结构,要么都是 32 位,要么都是 64 位。以下是检查 Python 架构的方法: import platform platform.architecture()
    3. 确保环境路径变量具有Oracle客户端到bin文件夹的完整路径。
    4. 确保将 TNS_ADMIN 变量设置为 TNS 文件所在的位置。
    5. 连接: import cx_Oracle conn = cx_Oracle.connect('<username>','<password>','<service name variable in your TNS file>') 此方法使用 TNS 文件中提供的连接详细信息,并且 cx_Oracle 从文件本身访问主机和端口详细信息。

    【讨论】:

      猜你喜欢
      • 2016-07-27
      • 2020-07-28
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2021-03-21
      • 2018-03-05
      • 2015-02-26
      相关资源
      最近更新 更多