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