前言
使用python连接oracle数据库的时候常用cx_oracle来连接,但是部分oracle数据库服务端采用us7ascii编码,导致读取出来的中文都是乱码的情况,研究了很久这个问题,网上也查了个遍,都没有很好的解决办法,偶然机会看了下cx_oracle的官方文档,换了个思路便完美解决了该问题。
直接上代码
import cx_Oracle
def output_type_handler(cursor, name, default_type, size, precision, scale):
# 输出类型处理程序,处理sql查询出来的varchar类型数据
if default_type == cx_Oracle.DB_TYPE_VARCHAR:
# 将输出采用gbk解码的方法
def convert_db_to_python_varchar(val):
return val.decode(encoding='gbk')
return
# bypass_decode=True,使得查询出来的内容不经过处理直接以byte方式输出,outconverter=将输出内容采用上面的方法解码
cursor.var(cx_Oracle.DB_TYPE_VARCHAR,arraysize=curso.arraysize, bypass_decode=True,outconverter=convert_db_to_python_varchar)
return None
# ***连接时候默认编码采用US-ASCII***
conn = cx_Oracle.connect('连接命令',encoding="US-ASCII",nencoding="UTF-8")
cursor = conn.cursor()
# 使用输出类型处理程序更改获取的数据类型
cursor.outputtypehandler = output_type_handler
cursor.execute ("select * from xx")
rows = cursor.fetchall() #得到所有数据集
for row in rows:
print(row)
cursor.close ()
conn.close ()
核心思想:cx_oracle出现中文乱码的核心原因主要还是客户端的解码编码问题,所以连接时候的encoding要和服务端一样,均为usascii编码,然后cx_oracle会获取ascii编码的内容,这个时候cx_oracle会默认采用utf_8解码,所以会出现乱码,采用官方文档的输出类型处理程序便可以处理。
网上搜到的常见的几种方案:
1.使用cast_to_raw,这个需要改sql,麻烦。
2.os.environ[‘NLS_LANG’] = ‘AMERICAN_AMERICA.US7ASCII’,无效。
等等
均不能很好解决该问题。
参考链接:
https://cx-oracle.readthedocs.io/en/latest/user_guide/sql_execution.html#