如何从Python访问Oracle?

时间:2010-08-19 12:24:18

标签: python oracle database-connection cx-oracle

如何从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.

我将不胜感激任何帮助。

9 个答案:

答案 0 :(得分:31)

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

我的版本:

  • Python 2.7
  • Oracle Instant Client 11G R2
  • cx_Oracle 5.0.4(Unicode,Python 2.7,Oracle 11G)
  • Windows XP SP3

<强>步骤:

  1. 下载Oracle Instant Client软件包。我使用了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 Instant Client目录。请参阅下面的oracle_python.bat源代码。我确信必须有一个更优雅的解决方案,但我想尽可能地限制我的系统范围的变化。确保将目标Oracle Instant Client目录放在PATH的开头(或至少在任何其他Oracle客户端目录之前)。现在,我只是做命令行的事情所以我只是在运行任何需要cx_Oracle的程序之前在shell中运行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源代码。请注意,我必须为我的cx_Oracle版本设置连接和SQL字符串为Unicode。
  6. 来源: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:期望无或字符串” - 如果需要将SQL字符串设置为Unicode。
    • “ImportError:DLL加载失败:找不到指定的过程。” - 可能表示cx_Oracle找不到合适的Oracle客户端DLL。

答案 1 :(得分:5)

以下是我的代码的样子。它还显示了如何使用字典使用查询参数的示例。它适用于使用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'})

答案 2 :(得分:3)

除了Oracle即时客户端之外,您可能还需要安装Oracle ODAC组件并将它们的路径放入系统路径中。 cx_Oracle似乎需要访问随它们安装的oci.dll文件。

同时检查您是否获得了与您的:python,cx_Oracle和即时客户端版本匹配的正确版本(32位或64位)。

答案 3 :(得分:2)

除了cx_Oracle之外,您还需要安装Oracle客户端库并正确设置路径以便cx_Oracle找到它 - 尝试在“Dependency Walker”(http://www.dependencywalker.com/)中打开cx_Oracle DLL以查看丢失的DLL是。

答案 4 :(得分:2)

确保这两个,它应该工作: -

  1. Python,Oracle instantclient和cx_Oracle是32位。
  2. 设置环境变量。
  3. 在Windows上修复此问题,就像魅力一样。

答案 5 :(得分:2)

如果您使用的是virtualenv,那么使用安装程序获取驱动程序并不是一件容易的事。你可以做什么:按照Devon的描述安装它。然后从Python \ Lib \ site-packages复制cx_Oracle.pyd和cx_Oracle-XXX.egg-info文件夹 从您的虚拟环境进入Lib \ site-packages。当然,在这里,架构和版本也很重要。

答案 6 :(得分:2)

您可以基于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()

OR

具有服务名称:

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

答案 7 :(得分:1)

请注意,如果您使用的是熊猫,则可以通过以下方式进行访问:

import pandas as pd
import cx_Oracle
conn= cx_Oracle.connect('username/pwd@host:port/service_name')
try:
    query = '''
         SELECT * from dual
             '''
    df = pd.read_sql(con = conn, sql = query)
finally:
    conn.close()
df.head()

答案 8 :(得分:1)

import cx_Oracle
   dsn_tns = cx_Oracle.makedsn('host', 'port', service_name='give service name') 
   conn = cx_Oracle.connect(user='username', password='password', dsn=dsn_tns) 
   c = conn.cursor()
   c.execute('select count(*) from schema.table_name')
for row in c:
   print row
conn.close()

注意:

  1. 如果需要,请在(dsn_tns)的(dsn_tns)中放置一个“ r”,以解决诸如“ \”之类的任何特殊字符。

  2. 如果需要,在(conn)中,在任何参数之前放置一个“ r”,以解决诸如“ \”之类的任何特殊字符。例如,如果您的用户名包含“ \”,则需要在用户名之前放置“ r”:user = r'User Name'或password = r'password'

  3. 如果要跨多行查询,请使用三引号。