公司近期有个需求,由于双十一的后遗症。。需要批量执行insert语句入库,因为手动去执行sql语句涉及到大量数据,以及dba人员相关工作量大,效率低问题,所以经老大讨论说要通过Python脚本去实现这个需求。
个人习惯是用pip 去安装,通过下面安装即可
pip install cx_Oralce
接下来看一下第三方库提供的官网:
https://oracle.github.io/python-cx_Oracle/index.html
现在的最新版本是cx_Oracle 6.xx系列了。根据官网看一下,需要满足的以下几点(自己翻译的,有的地方可能不通顺,意思出来了,懂了就好~):
Support for Python 2 and 3. 支持了Python2和3。
Support for Oracle Client 11.2, 12.1 and 12.2. Oracle’s standard cross-version interoperability, allows easy upgrades and connectivity to different Oracle Database versions.
支持Oracle客户端11.2,12.1和12.2 ,Oralce的标准版本的互用性,允许简单的更新和连接不同的oracle版本。
Connect to Oracle Database 9.2, 10, 11 or 12 (depending on the Oracle Client version used). 连接oracle 9.2,10,11,12(依赖于oracle客户端的版本)
还有一些别的tips,此处不在一一例举了,通过以上三点了解到了,此库需要的条件,我本地是Python3.6这点支持,接下来是客户端的版本需要对应上了。
接下来看一下demo:
import cx_Oracle
#下面的代码对应的解释
#connection = cx_Oracle.connect("用户名", "密码", "ip地址/库名字")
connection = cx_Oracle.connect("hr", "welcome", "localhost/orclpdb")
#创建游标
cursor = connection.cursor()
#通过游标去执行对应的sql语句
cursor.execute("""
SELECT first_name, last_name
FROM employees
WHERE department_id = :did AND employee_id > :eid""",
did = 50,
eid = 190)
for fname, lname in cursor:
print("Values:", fname, lname)
把上面对应的参数修改成你需要的即可。
我本地的Oracle客户端版本是Oracle9i 简装版,而我用到的cx_Oracle版本是6.xx ,当我用参考demo写好的代码之后,去连接测试数据库时,第一次错误报的就是:
DPI-1049: symbol OCIClientVersion not found in OCI library
这个错误代码经过大量的网上查阅也没有查到相关资料,后来再去官网对应看的时候,才发现是自己的Oralce客户端版本与第三库版本对不上,正如上面所说的三点,支持的是9.2的客户端。
于是我果断卸载了Oracle9i简装版,去网上下载了一个Oracle11g的客户端简装版安装上了。这个给出csdn的下载地址吧。。。花了我13C币呢= =。。也是csdn上的资源。。。下载资源如下:
http://pan.baidu.com/s/1gf4aaob
再次跑demo运行的时候,上面的错误消失!此时说明了确实是版本不统一导致的OCI库中没有发现对应的OCIClient。
但是新问题也随之而来,就是报出了
‘utf-8’ codec can’t decode bytes in position 82-83: invalid continuation byte
而对应的Python代码报错行是下面这行:
connection = cx_Oracle.connect("hr", "welcome", "localhost/orclpdb")
通过网盘中简装版安装的客户端默认编码及不是utf-8的编码。。也不是gbk的编码,我是如何去排错的呢?
用plsql连接对应随意的一个库,然后输入:
--这句话可以查出当前客户端的字符集
select * from sys.nls_session_parameters;
而我默认字符集是美国的。。。
修改Oracle客户端字符集编码!
此处还可以用sql查询Oralce服务端编码:
select userenv ('language') from dual;
可以看到服务端也是gbk的编码格式….
言归正传,接下来寻找解决方案,如下:
打开cmd,输入regedit,进入注册表:
由于是简装版的Oracle客户端,所以在下面的路径中并没有Oralce这个选项,
但是皇天不负苦心人,最终让我搜索到了,简装版的修改语言字符集的路径!如下:
依然进入这个路径,虽然没有Oracle,但是有如下的路径:
双击NLS_LANG,即可弹出一个框框,把下面的英文复制进去就是中文字符集了,这里是GBK的形式
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
待周一去公司的测试环境测试一下是否成功了!先留个记录。。。。
2017-11-27 更新实验结果
实验表明,修改完成后确实不会再次出现编码问题了。。。。。连接成功!
但是需要注意的是,通过这种方式去执行Oralce的sql语句最后不要外加分号!否则会报如下的错误。。。
至此完!
更新于20180212
举个例子,批量插入数据库的sql写法:
#批量插入的sql语句
sql = ("INSERT INTO student (id,name,age) VALUES "
"(:1,:2,:3)"
)
#对应着创建一个list
sql_vaules=[]
sql_vaules.append("1")
sql_vaules.append("小明")
sql_vaules.append("16")
try:
db = cx_Oracle.connect(username, password, 数据库ip/数据库名称)
cr = db.cursor()
#第一个参数是sql语句,第二个参数是sql语句中的变量,此参数需要是tuple,或者是list类型
cr.executemany(sql, sql_vaules)
#提交事务
db.commit()
except Exception as e:
db.rollback()
finally:
# 关闭游标,同时关闭连接
cr.close()
db.close()