Python访问Oracle及注意事项

Python访问Oracle及注意事项

这两天一直在捣鼓使用Python访问Oracle,主要是因为要将数据批量导入数据库。
说到批量导入首先想到的是Oracle的sqlloader工具了,不过这个要求安装有Oracle客户端,Oracle的客户端可是有一两个G呐,难道为了导数据就要安装这个庞然大物吗?
百度了一下Python连接Oracle方法,发现很多人都在用cx_oracle这个Python的模块,看了下具体的使用方法,也挺简单的,而且有批量导入的函数。高兴了一下下,就是纠结为什么cx_oracle这么难安装呢。想想也是,Oracle数据库虽然很轻大,但是要访问它还是挺费事的,要安装instantclient,oci.dll什么的,想想pl/sql就知道了。
在参考了广大网友的方法后,特地做些笔记。

1.安装oracle客户端instantclient

这个是Python扩展包所需要的,可以到http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html下载,我下载的是 instantclient-basic-windows.x64-11.2.0.4.0,虽然公司的数据库是10.2的,但是也能用,我想应该是向下兼容的吧。
- 解压 instantclient-basic-windows.x64-11.2.0.4.0.zip 到 D:\instantclient
- 将D:\instantclient添加值path环境变量
- 增加环境变量:TNS_ADMIN ,值为 D:\instantclient,也就是解压的目录
- 增加环境变量:NLS_LANG ,值为 SIMPLIFIED CHINESE_CHINA.ZHS16GBK,这是为了防止中文乱码
- 创建一个监听文件tnsnames.ora到D:\instantclient,也可以从其他地方复制一个过来,里面的内容可以参考下面的:

mytns =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.122)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

2.安装cx_Oracle-5.2.1-11g.win-amd64-py3.5.exe

到https://pypi.python.org/pypi/cx_Oracle/5.2.1下载版本对应的cx_oracle,注意要和Python的版本对应,要和windows的位数对应,比如我是Python3.5 64位,win7 64位,oracle客户端instantclient是11g的。
下载后直接安装就好了。
在它的项目网站http://cx-oracle.sourceforge.net/说可以用pip install cx_Oracle(注意大小写),但是报错说没有vs.bat什么的,说是没有vs运行编译环境。但是可以安装其他的程序包啊,不太明白。但是使用exe安装方式没有问题。

3.cx_oracle简单使用

-- 创建连接
import cx_Oracle
--cx_Oracle.connect('用户名', '密码', 'ip:1521/oracle的serve_name')
conn=cx_Oracle.connect('用户名', '密码', '192.168.1.122:1521/orcl')
cursor = conn.cursor()

-- 查询数据
cursor.execute(sql)
result=cursor.fetchall()

-- 插入,更新,删除
cursor.execute(sql)
conn.commit()

-- 批量插入
-- 先在Python中将数据整理成list-tuple格式
-- 比如:
param = [("id1","name1","score1"),("id2","name2","score2")]
-- 做准备
cursor.prepare('insert into table_name(id, name, score) values(:1, :2, :3)')
-- 一次执行多行语句
cursor.executemany(None, param)
-- 提交
conn.commit()

-- 带参数的查询
named_params = {'dept_id':50, 'sal':1000}
query1 = cursor.execute('SELECT * FROM employees 
WHERE department_id=:dept_id AND salary>:sal', named_params)

query2 = cursor.execute('SELECT * FROM employees     WHERE department_id=:dept_id AND salary>:sal', dept_id=50, sal=1000)

-- 当只有一次参数的时候,也要把它写成元组的形式,比如
Cursor.execute(‘select name from user where id=:1’,(login_Id,))

-- 千万要注意,login_id后面还带有一个逗号,如果没有逗号,他其实就是一个数据对象,但是当他后面有个逗号的时候,他就变成了元组的一个数据项,千万要记住啊,我就是在这里徘徊了很久。!


-- 调用存储过程和方法
cursor.callproc('proc_name',[var1,var2])

注意事项1

一般来说,oracle的字符编码是 SIMPLIFIED CHINESE_CHINA.ZHS16GBK,虽然可以直接通过pd.read_sql导出数据,但是不可避免会出现乱码无法解析而错误,就算是用fetchall这样的函数也会错误。
此时需要设置 os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
就可以避免乱码导致的错误。

注意事项2

如果希望通过python调用cmd从oracle导入导出数据,也就是python调用cmd,cmd调用sqlloader或者sqluldr2导入导出数据,此时需要将NLS_LANG设置为和oracle一样的字符集,否则会报错,而且就算可以导入导出还是乱码。即 os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.ZHS16GBK'

你可能感兴趣的:(Python,oracle)