记一次Python连接Oracle,报错编码不匹配问题

来源:互联网 发布:剑灵人捏脸数据 编辑:程序博客网 时间:2024/06/16 05:53

起因

公司近期有个需求,由于双十一的后遗症。。需要批量执行insert语句入库,因为手动去执行sql语句涉及到大量数据,以及dba人员相关工作量大,效率低问题,所以经老大讨论说要通过Python脚本去实现这个需求。

编码之路

环境

  • Python3.6
  • Windows10
  • 设计到的第三方库 —— cx_Oracle

cx_Oracle的安装及注意

个人习惯是用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语句最后不要外加分号!否则会报如下的错误。。。

这里写图片描述

至此完!