如何从Python访问Oracle?

40 投票
10 回答
189865 浏览
提问于 2025-04-16 03:01

我该如何从Python访问Oracle数据库呢?我下载了一个cx_Oracle的安装包,但是Python却无法导入这个库。

我遇到了以下错误:

import cx_Oracle

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    import cx_Oracle
ImportError: DLL load failed: The specified module could not be found.

如果有人能帮我,我将非常感激。

10 个回答

14

你可以根据你手头有的内容,选择以下任意一种方式,使用服务名称或者SID

使用SID:

import cx_Oracle
dsn_tns = cx_Oracle.makedsn('server', 'port', 'sid')
conn = cx_Oracle.connect(user='username', password='password', dsn=dsn_tns)
c = conn.cursor()
c.execute('select count(*) from TABLE_NAME')
for row in c:
   print(row)
conn.close()

或者

使用服务名称:

import cx_Oracle
dsn_tns = cx_Oracle.makedsn('server', 'port', service_name='service_name')
conn = cx_Oracle.connect(user='username', password='password', dsn=dsn_tns)
c = conn.cursor()
c.execute('select count(*) from TABLE_NAME')
for row in c:
   print(row)
conn.close()
14

这是我的代码示例。它还展示了如何使用字典来处理查询参数。这个代码适用于Python 3.6:

import cx_Oracle

CONN_INFO = {
    'host': 'xxx.xx.xxx.x',
    'port': 12345,
    'user': 'SOME_SCHEMA',
    'psw': 'SECRETE',
    'service': 'service.server.com'
}

CONN_STR = '{user}/{psw}@{host}:{port}/{service}'.format(**CONN_INFO)

QUERY = '''
    SELECT
        *
    FROM
        USER
    WHERE
        NAME = :name
'''


class DB:
    def __init__(self):
        self.conn = cx_Oracle.connect(CONN_STR)

    def query(self, query, params=None):
        cursor = self.conn.cursor()
        result = cursor.execute(query, params).fetchall()
        cursor.close()
        return result


db = DB()
result = db.query(QUERY, {'name': 'happy'})
38

这是我成功的步骤。我的Python和Oracle版本跟你们的稍微有点不同,但这个方法应该是适用的。只要确保cx_Oracle的安装包版本和你的Oracle客户端及Python版本相匹配就行。

我的版本:

  • Python 2.7
  • Oracle即时客户端 11G R2
  • cx_Oracle 5.0.4(Unicode,Python 2.7,Oracle 11G)
  • Windows XP SP3

步骤:

  1. 下载Oracle即时客户端包。我用的是instantclient-basic-win32-11.2.0.1.0.zip。解压到C:\your\path\to\instantclient_11_2。
  2. 下载并运行cx_Oracle的安装包。我用的是cx_Oracle-5.0.4-11g-unicode.win32-py2.7.msi。我为所有用户安装,并指向注册表中找到的Python 2.7的位置。
  3. 通过批处理脚本或其他适合你应用的方式设置ORACLE_HOME和PATH环境变量,让它们指向Oracle即时客户端目录。可以参考下面的oracle_python.bat源代码。我相信应该有更优雅的解决方案,但我想尽量减少对系统的改动。确保把目标Oracle即时客户端目录放在PATH的最前面(或者至少在其他Oracle客户端目录之前)。目前我只是在命令行操作,所以在运行任何需要cx_Oracle的程序之前,我会先在命令行中运行oracle_python.bat。
  4. 运行regedit,检查\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE下是否有NLS_LANG这个键。如果有,重命名这个键(我把它改成了NLS_LANG_OLD)或者删除它。这个键只应该作为Oracle 7客户端的默认NLS_LANG值使用,所以如果你没有在其他地方使用Oracle 7客户端,删除它是安全的。像往常一样,修改之前一定要备份你的注册表。
  5. 现在,你应该可以在你的Python程序中导入cx_Oracle了。可以参考下面的oracle_test.py源代码。注意,我需要把连接和SQL字符串设置为Unicode,以适应我版本的cx_Oracle。

源代码:oracle_python.bat

@echo off
set ORACLE_HOME=C:\your\path\to\instantclient_11_2
set PATH=%ORACLE_HOME%;%PATH%

源代码:oracle_test.py

import cx_Oracle

conn_str = u'user/password@host:port/service'
conn = cx_Oracle.connect(conn_str)
c = conn.cursor()
c.execute(u'select your_col_1, your_col_2 from your_table')
for row in c:
    print row[0], "-", row[1]
conn.close()

可能遇到的问题:

  • “ORA-12705: 无法访问NLS数据文件或指定的环境无效” - 在我修改NLS_LANG注册表之前,我遇到过这个问题。
  • “TypeError: 参数1必须是unicode,而不是str” - 如果你需要把连接字符串设置为Unicode。
  • “TypeError: 期待None或字符串” - 如果你需要把SQL字符串设置为Unicode。
  • “ImportError: DLL加载失败:找不到指定的过程。” - 可能表示cx_Oracle找不到合适的Oracle客户端DLL。

撰写回答