python3.6 cx_oracle连接数据库报编码错UnicodeDecodeError

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python3.6 cx_oracle连接数据库报编码错UnicodeDecodeError相关的知识,希望对你有一定的参考价值。

File "D:\workspace python\LastTree3\src\ConnectionORCL.py", line 17, in connection
db=cx_Oracle.connect(username,password,tns)
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 82-83: invalid continuation byte

我说下我遇到的情况

数据库字符集是 ZHS16GBK

错误的情况是

UnicodeDecodeError: 'gbk' codec can't decode byte 0xa7 in position 12: illegal multibyte sequence

经过检查,在fetchall()获取记录时,查询到的记录里面有乱码(应该是不包含在数据库现有字符集下的字符)

临时的一个解决办法是

db=cx_Oracle.connect(dblink,encoding='UTF-8')

这样可以读取了,读取到的内容为

广州市\\ue738同泰路

其中 '\\ue738'应该是之前不可被读取的字符,希望对各位有帮助

参考技术A python3.6 cx_oracle连接数据库报编码错UnicodeDecodeError
# -*- coding:utf-8 -*-
#!/usr/bin/env python
'''
Created on 2014年8月4日

@author: 188007

连接Oracle数据库的class
'''
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.ZHS16GBK'
import cx_Oracle
import sys

class Oracle:
'''
python access oracle helper tool class
'''

def __init__(self, ip,port,db,user,pwd):
self.ip = ip
self.port = port
self.db = db
self.user = user
self.pwd = pwd

def __GetConnect(self):
""" 得到连接信息 返回: conn.cursor() """
if not self.db:
raise(NameError,"没有设置数据库信息")
dsn=cx_Oracle.makedsn(self.ip,self.port,self.db)
self.conn=cx_Oracle.connect(self.user,self.pwd,dsn)
cur = self.conn.cursor()
if not cur:
raise(NameError,"连接数据库失败")
else:
return cur

def ExecQuery(self,sql):
""" 执行查询语句 返回的是一个包含tuple的list,list的元素是记录行,tuple的元素是每行记录的字段
调用示例:
oracle = Oracle('10.27.95.253','1561','GFDMS','GFITAPPS','GFITAPPS')
resList = oracle.ExecQuery("SELECT OBJID,NUMCODE,AREACODE,AREANAME,PROVCODE,PROVNAME,CITYCODE,CITYNAME,TOWNCODE,TOWNNAME,REMARK FROM GFDMS.THZONE ORDER BY NUMCODE")
for (AREANAME) in resList:
print str(AREANAME).decode('gb2312')
"""
try:
cur = self.__GetConnect()
cur.execute(sql)
resList = cur.fetchall()

#查询完毕后必须关闭连接
self.conn.close()
except Exception, err:
sys.exit(1)

return resList

def ExecNonQuery(self,sql):
""" 执行非查询语句
调用示例:
oracle.ExecNonQuery("insert into THZONE values('x','y')")
"""
try:
cur = self.__GetConnect()
cur.execute(sql)
self.conn.commit()
self.conn.close()
except Exception, err:
sys.exit(1)

# def main():
# # oracle = Oracle('10.27.95.253','1561','GFDMS','GFITAPPS','GFITAPPS')
# # #返回的是一个包含tuple的list,list的元素是记录行,tuple的元素是每行记录的字段
# # oracle.ExecNonQuery("insert into THZONE values('x','y')")
# oracle = Oracle('10.27.95.253','1561','GTEST','GTAPPS','GTAPPS')
# resList = oracle.ExecQuery("SELECT OBJID,NUMCODE,AREACODE,AREANAME,PROVCODE,PROVNAME,CITYCODE,CITYNAME,TOWNCODE,TOWNNAME,REMARK FROM GTEST.THZONE ORDER BY NUMCODE")
# for (AREANAME) in resList:
# print str(AREANAME).decode('utf-8')
#
# if __name__ == '__main__':
# main()追问

我还在windows下搞的,今天一大早重启机器后,它就好了,不知道什么愿意,不过还是谢谢

本回答被提问者和网友采纳
参考技术B 您这个问题解决了没?怎么解决的?能教教我吗?

cx_Oracle连接数据库总结

python中连接oracle数据库使用第三方库文件cx_Oracle时遇到了各种问题,网上查找资料调试了几天才弄好,下面是不断调试后总结的一些经验。
1.oracle客户端(Oracle Instant Client)版本需要和操作系统版本位数相同,同时cx_Oracle官方文档(http://cx-oracle.readthedocs.io/en/latest/installation.html)上有这样一段话

Version 12.2 client libraries can connect to Oracle Database 11.2 or greater. Version 12.1 client libraries can connect to Oracle Database 10.2 or greater. Version 11.2 client libraries can connect to Oracle Database 9.2 or greater.
根据安装的Oracle数据库版本选择Oracle客户端(下载地址 http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html),我安装的oracle数据库是11g版本,这里的客户端库在下载客户端Oracle Instant Client时就包含在内

下载好oracle客户端后,在客户端目录下新建一/network/admin目录,并在该目录下新建tnsnames.ora文件,增加自己的数据库别名配置。
示例如下:

1 MyDB=
2 (DESCRIPTION =
3 (ADDRESS = (PROTOCOL = TCP)(HOST= IP)(PORT = 1521))
4 (CONNECT_DATA =
5 (SERVER = DEDICATED)
6 (SERVICE_NAME = )
7 )
8 )

注意格式要排列好
MyDB为Database名,Host为IP地址, SERVICE_NAME为数据库服务器的实例名。

2.安装的python版本位数也需与操作系统版本位数相同

3.安装的第三方库cx_Oracle需要版本位数和操作系统相同同时,与Oracle数据库对应的版本也应相同,因我安装的数据库是11g,所以下载的是cx_Oracle-5.3-11g.win-amd64-py3.5-2 若安装的数据库是12c则应下载相应版本cx_Oracle(地址 https://pypi.python.org/pypi/cx_Oracle/5.3)

同时可能出现的其他问题在cx_Oracle官方文档中也写出了
1. DPI-1047: Oracle Client library cannot be loaded
Check that Python, cx_Oracle and your Oracle Client libraries are all 64-bit or all 32-bit. The DPI-1047 message will tell you whether the 64-bit or 32-bit Oracle Client is needed for your Python.
检查python,cx_Oracle和Oracle Instant Client版本是否一致,DPI-1047 message会告诉你安装的客户端版本是否正确。

2.On Windows, restart your command prompt and use set PATH to check the environment variable has the correct Oracle Client listed before any other Oracle directories.
记得配置Oracle客户端的环境变量,例如我的配置是 PATH: E:\oracle\instantclient_12_2;

3.On Windows, use the DIR command on the directory set in PATH. Verify that OCI.DLL exists there.
检查oracle客户端(instantclient)目录下存在oci.dll文件

4.On Windows, check that the correct Windows Redistributables have been installed.
oracle客户端libraries需要正确的Visual Studio版本,具体可见(https://oracle.github.io/odpi/doc/installation.html#windows)中windows目录下

On Linux, check the LD_LIBRARY_PATH environment variable contains the Oracle Client library directory.
On macOS, make sure Oracle Instant Client is in ~/lib or /usr/local/lib and that you are not using the bundled Python (use Homebrew or Python.org instead).

最后一切就绪,程序未出错,但并无输出时感觉内心有些崩溃

 1 import cx_Oracle
 2 
 3 connection = cx_Oracle.Connection("Username/密码@Host:Port/SERVICE_NAME")
 4 cursor = connection.cursor()
 5 
 6 try:
 7   cursor.execute("select 1 / 0 from dual")
 8 except cx_Oracle.DatabaseError as exc:
 9   error, = exc.args
10 print("Oracle-Error-Code:", error.code)
11 print("Oracle-Error-Message:", error.message)

最后查看意识到是执行了sql语句,但并未进行输出

cursor.execute("select 1 / 0 from dual")

 


下一行增加
 print(cursor.description) 
便可以看见查找到的数据库中的内容
















以上是关于python3.6 cx_oracle连接数据库报编码错UnicodeDecodeError的主要内容,如果未能解决你的问题,请参考以下文章

centos6.5编译安装python3.6.3和cx_oracle

python3.6的安装及cx_oracle安装

Linux下使用Python连接Oracle 报cx_Oracle.DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be lo

django连接Oracle过程中出现的问题

python之Oracle操作(cx_Oracle)

django中进行migrate时报错:cx_Oracle.DatabaseError: ORA-02000: missing ALWAYS keyword