如何从Python访问Oracle?

2024-04-26 12:38:08 发布

您现在位置:Python中文网/ 问答频道 /正文

如何从Python访问Oracle?我下载了一个cx_Oracle msi安装程序,但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.

我将感激你的帮助。


Tags: importmost错误linecallfileoraclemsi
3条回答

这是对我有用的。我的Python和Oracle版本与您的略有不同,但应该采用相同的方法。只需确保cx_Oracle二进制安装程序版本与您的Oracle客户端和Python版本匹配即可。

我的版本:

  • Python2.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。我为所有用户安装了它,并将其指向在注册表中找到的Python2.7位置。
  3. 通过批处理脚本或任何在应用程序上下文中有意义的机制设置ORACLE_HOME和PATH环境变量,以便它们指向ORACLE Instant Client目录。请参阅下面的oracle_python.bat源代码。我相信一定有一个更优雅的解决方案,但我想限制我的系统范围内的变化尽可能多。确保将目标Oracle Instant Client目录放在路径的开头(或至少放在任何其他Oracle Client目录的前面)。现在,我只做命令行的工作,所以在运行任何需要cx_oracle的程序之前,我只是在shell中运行oracle_python.bat。
  4. 运行regedit并检查是否在\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE处设置了NLS_LANG密钥。如果是,请重命名密钥(我将其更改为NLS_LANG_OLD)或取消设置。此密钥只能用作Oracle7客户端的默认NLS语言值,因此可以安全地删除它,除非您碰巧在其他地方使用Oracle7客户端。和往常一样,在进行更改之前一定要备份注册表。
  5. 现在,您应该可以在Python程序中导入cx_Oracle了。请参阅下面的oracle_test.py源代码。注意,对于我的cx_Oracle版本,我必须将连接和SQL字符串设置为Unicode。

来源: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语言注册表之前,我遇到了此问题。
  • “TypeError:参数1必须是unicode,而不是str”-如果需要将连接字符串设置为unicode。
  • “TypeError:应为None或string”-如果需要将SQL字符串设置为Unicode。
  • “ImportError:DLL加载失败:找不到指定的过程。”-可能表示cx\u Oracle找不到相应的Oracle客户端DLL。

我的代码是这样的。它还展示了如何使用字典来使用查询参数的示例。它可以使用Python3.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'})

您可以基于Service NameSID使用以下任何方法。

使用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()

相关问题 更多 >