如何从Python访问Oracle?

如何从Python访问Oracle?,python,oracle,database-connection,cx-oracle,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

如何从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.
导入cx\u Oracle
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
导入cx_Oracle
ImportError:DLL加载失败:找不到指定的模块。

我将非常感谢您的帮助。

除了cx_Oracle之外,您还需要安装Oracle客户端库并正确设置路径,以便cx_Oracle能够找到它-请尝试在“Dependency Walker”(依赖项Walker)()中打开cx_Oracle DLL,看看缺少的DLL是什么。

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

我的版本:

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()
  • Python 2.7
  • Oracle即时客户端11G R2
  • cx_Oracle 5.0.4(Unicode、Python 2.7、Oracle 11G)
  • WindowsXPSP3
步骤:

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()
  • 下载Oracle即时客户端软件包。我使用instantclient-basic-win32-11.2.0.1.0.zip。将其解压缩到C:\your\path\to\instantclient\u 11\u 2
  • 下载并运行cx_Oracle二进制安装程序。我使用了cx_Oracle-5.0.4-11g-unicode.win32-py2.7.msi。我为所有用户安装了它,并将它指向在注册表中找到的Python2.7位置
  • 通过批处理脚本或在应用程序上下文中有意义的任何机制设置ORACLE_HOME和PATH环境变量,以便它们指向ORACLE Instant Client目录。请参阅下面的oracle_python.bat源代码。我肯定会有一个更优雅的解决方案,但我想尽可能地限制系统范围内的更改。确保将目标Oracle Instant Client目录放在路径的开头(或至少放在任何其他Oracle客户端目录的前面)。现在,我只做命令行工作,所以在运行任何需要cx_oracle的程序之前,我只在shell中运行oracle_python.bat
  • 运行regedit并检查\HKEY\u LOCAL\u MACHINE\SOFTWARE\ORACLE是否设置了NLS\u LANG密钥。如果是这样,请重命名密钥(我将其更改为NLS_LANG_OLD)或取消设置它。此密钥应仅用作Oracle 7客户端的默认NLS_LANG值,因此删除它是安全的,除非您碰巧在其他地方使用Oracle 7客户端。一如既往,在进行更改之前,请确保备份注册表
  • 现在,您应该能够在Python程序中导入cx_Oracle了。请参阅下面的oracle_test.py源代码。注意,对于我的cx\U 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()
    
    可能的问题:

    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()
    
    • “ORA-12705:无法访问NLS数据文件或指定的环境无效”-在更改NLS_LANG注册表之前,我遇到了此问题
    • “TypeError:参数1必须是unicode,而不是str”-如果需要将连接字符串设置为unicode
    • “TypeError:应为None或string”-如果需要将SQL字符串设置为Unicode
    • “ImportError:DLL加载失败:找不到指定的过程。”-可能表示cx\U Oracle找不到适当的Oracle客户端DLL

    除了Oracle instant client,您可能还需要安装Oracle ODAC组件,并将其路径放入系统路径中。cx_Oracle似乎需要访问随它们一起安装的oci.dll文件


    另外,请检查您是否获得了与您的:python、cx_Oracle和instant client版本相匹配的正确版本(32位或64位)。

    确保这两个版本都有效:-

  • Python、Oracle instantclient和cx_Oracle是32位的
  • 设置环境变量

  • 在windows上很好地解决了这个问题。

    如果您使用的是virtualenv,那么让驱动程序使用安装程序就不是那么简单了。然后您可以做什么:按照Devon的描述安装它。然后从Python\Lib\site包中复制cx_Oracle.pyd和cx_Oracle-XXX.egg-info文件夹
    从虚拟环境导入Lib\site包。当然,在这里,架构和版本也很重要。

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

    注意:如果您正在使用pandas,您可以通过以下方式访问它:

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

    注:

  • 在(dsn\U tns)中,如果需要,在任何参数之前放置一个“r”,以寻址任何特殊字符,如“\”

  • 在(conn)中,如果需要,在任何参数之前放置一个“r”,以寻址任何特殊字符,如“\”。例如,如果您的用户名包含“\”,则需要在用户名前面加上“r”:user=r'user name或password=r'password

  • 如果要将查询分散到多行,请使用三重引号


  • 您可以根据
    服务名称
    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()
    

    服务名称:

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

    您下载了哪款cx_Oracle。另外,您使用的是哪种版本的Python、哪种版本的Oracle以及哪种操作系统?cx_Oracle-5.0.2-10g.win32-PY26听起来可能不会被提取到Python用于查找模块的路径中。您是否尝试过使用easy_install而不是显式安装它(可能缺少另一个依赖项)。此特定错误意味着Oracle客户端OCI DDL是为不同的平台编译的。32位vs 64或Intel vs AMD。这不是故意的,但不知道这是如何产生的。有人知道,只要所有版本号和平台保持一致,这是否适用于其他版本(即3.4?和64位)吗?@TheRedPea这对我来说适用于ve