cx_oracle读取数据指定编码,SQLAlchemy和cx_Oracle使用中碰到的数据库编码问题
1. 系统结构及问题最近在搭建基于Jupyter notebook,panda,dash plotly的数据分析系统。从各个业务系统抽取数据,分析展示。
难免会涉及到中间数据保存,最后返现还是绕不开数据库。为了方便选了Oracle XE,看重其pluggable PDB实在是方便,每个库还可以不同字符编码,兼容各个业务系统。
然鹅,当我用pd.to_sql输出到DB的时候,却发现各种编码问题,并不是SQLAlchemy create engine的时候指定编码就能解决的。
2. 数据读取当业务系统库是UTF-8,我在XE DB中建了一个UTF-8的PDB,本已实现免除encoding转换。各库中都保留原来的编码,python中提取之后都是unicode,理想很完美。
现实是当我用cx_Oracle读取UTF-8业务库的数据,pandas中数据内容很正常。
此处穿件连接的encoding选项功能很正常。1
2
3con = cx_Oracle.connect(data_driver.MAIN_CONNECT_STRING,encoding="UTF-8")
df_all = pd.read_sql_query(con=con, sql=str_sql)
3. 数据写入PDB写入数据库时,如果直接用cx_Oracle驱动代码比较麻烦,一般直觉肯会用Pandas的DataFrame.to_sql。这样底层的令人痛疼的create table, insert 都一边去,自己要做的就是在pandas里面整理数据,to_sql扔给数据库持久化保存。从效率来看,to_sql也远比 to_excel效率高,节省资源。
写入数据库,代码节大概如下。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#这里按照文档,用了encoding='utf-8'。 双方数据都是utf-8编码,正常应该没问题。
engine = create_engine('oracle://' + 'utf-8')
#查看数据库编码,确实是 SIMPLIFIED CHINESE_CHINA.AL32UTF8
engine.execute("select userenv('language') from dual").fetchall()
#写数据
df_all.to_sql(name='表明_table'
,con=engine # utf-8 的sqlalchemy engine
,if_exists='replace'
,chunksize=10000
,dtype={ 'column name' : sqlalchemy.types.VARCHAR(10) # 对于pandas中object的列,要定义类型,否则。。。自动clob也是慢
}
,index=False
)写代码的时候自信满满以为照顾到了各方编码,结果还是出来GBK编码错误. 数据中心有'xa0'全角空格,gbk无法编码。
返回错误1UnicodeEncodeError: 'gbk' codec can't encode character 'xa0' in position 0: illegal multibyte sequence
4. 问题排查及解决错误出来之后,首先想到的是数据库编码有问题。
重复检查数据库,确实双方都是UTF-8, 分析用的XE PDB中也确实是UTF-8, 手工录入'xa0'都没有问题。所以排除数据库自身编码的问题。
其次想到的是操作系统默认编码,因为服务器是windows,通过chcp 650001,改变默认编码为unicode,在启动python,这样貌似没地方会使gbk编码了吧。应该完美了。
测试之后,还是被打脸了,错误信息一点变化都没有。
最后想排查cx_Oracle 和SQLAlchemy 这两个库。
读取数据的时候pandas直接使用的cx_Oracle 连接,指定utf-8编码之后数据是正常的,所以基本上定位是SQLAlchemy的问题。
创建engine的时候,这里指定的encoding是否有效存疑啊。看来还是SQLAlchemy和cx_Oracle集成的时候出现了问题。1engine = create_engine('oracle://' + 'utf-8')翻了几篇官方文档,试了各种。。。。此处省略一万种选择。最后找到希望
SQLAlchemy对于创建 engine这件事情,提供了深度客制化的选择。对于cx_Oracle兼容不太满意的情况,可以自己建一个creator,保证cx_Oracle的配置都做好之后,再传给SQLAlchemy。
代码示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 定义基于cx_Oracle的creator,在里面生成connection,保证使用UTF-8编码。这是能正常work的,在读取的时候也验证过。
def ():
return cx_Oracle.connect("UTF-8")
#连接库生成SQLAlchemy engine时,调用creator,这时encoding写上就写上吧,可能真没用。
engine = create_engine('oracle+cx_oracle://', creator=con_creator ,encoding='utf-8')
#写数据,这回没有烦人的encoding 错误了。拜拜了gbk
df_all.to_sql(name='表明_table'
,con=engine # utf-8 的sqlalchemy engine
,if_exists='replace'
,chunksize=10000
,dtype={ 'column name' : sqlalchemy.types.VARCHAR(10) # 对于pandas中object的列,要定义类型,否则。。。自动clob也是慢
}
,index=False
)
摆脱了这个编码问题,继续我建设功能感人的数据分析平台之路。
cx_oracle读取数据指定编码,SQLAlchemy和cx_Oracle使用中碰到的数据库编码问题相关推荐
- mysql 查看当前数据库编码方式_MySQL查看与修改当前数据库编码的方法
MySQL中,数据库的编码是一个相当重要的问题,有时候我们需要查看一下当前数据库的编码,甚至需要修改一下数据库编码. 查看当前数据库编码的SQL语句为: mysql> use xxx Datab ...
- mysql 查询编码转换_字符集介绍及mysql数据库编码转换
一.字符集介绍: 1.ASCII ASCII是英文American Standard Code for Information Interchange的缩写,美国标准信息交换代码是由美国国家标准学会( ...
- python读数据-如何用 Python 读取数据?
原标题:如何用 Python 读取数据? 这是林骥的第 36 篇文章 1. 序言 读取数据往往是做数据分析的第一步,本文没有讲那些艰涩难懂的概念,只有一些问题的解决方案,当你遇到类似的问题的时候,可以 ...
- php读取数据显示乱码,php读取数据乱码怎么办
php读取数据乱码的解决办法:首先将php网页编码设置为"UTF-8":然后连接数据库并插入代码为"$program_char="utf8";mysq ...
- 设置MYSQL数据库编码为UTF-8:
设置mysql数据库显示编码:set charset utf8; 查看mysql数据库编码:show variables like 'character%'; 在这个过程中如果出现了数据库编码 ...
- python编码与存储读取数据(数组字典)
Camp时在python2的编码上坑了不少. 理解pyhon2的编码 python2字符串类型只有两种: str类型:b'xxx'即是str类型, 是编码后的类型,len()按字节计算 unicode ...
- pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头、pandas使用to_csv函数将dataframe保存为gzip压缩文件
pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头.pandas使用to_csv函数将dataframe保存为gzip压缩文件 目录
- python 在excel指定列添加数据_python读取excel指定列数据并写入到新的excel方法
如下所示: #encoding=utf-8 import xlrd from xlwt import * #------------------读数据------------------------- ...
- 如何创建最简单的 ABAP 数据库表,以及编码从数据库表中读取数据 (上) 试读版
ABAP 标准培训教程 BC400 学习笔记之一:ABAP 服务器的架构和一个典型的 ABAP 程序结构介绍 ABAP 标准培训教程 BC400 学习笔记之二:Cross-client 和 Clien ...
最新文章
- CleanMyMac扩展管理功能
- MySQL参数优化辅助工具_mysqltuner.pl
- [网络安全提高班] 一〇一.网络攻防溯源普及和医疗数据安全总结
- [每天一个知识点]3-程序员的三大美德(2)
- exxi6.7如何传文件到win7_比QQ直传快100倍!它让PC、安卓、iPhone光速互传文件
- 前端学习(3337):ant design中button按钮尺寸size
- Mysql字段修饰符(约束)
- 为什么PostgreSQL是最先进的开源数据库
- 图说:Windows 8 Copy的呈现变化
- (扫盲)WebSocket 教程
- 微信公众平台开发,图文回复、access_token生成调用、以及微信SDK的实现(2)
- 计算机组成原理 笔记 第二版 唐朔飞
- protel相关资料
- 升级版4850竖曲线
- KK课表抓取教务系统
- 工作-safari时间格式
- 计算机中字符的表示方法
- Http请求全过程简述
- JS数组转字符串传到JAVA后端取出
- 敏捷开发篇--Agile Development-自用
热门文章
- java web jsp的银行柜员绩效考核系统
- macOS 安装 Adobe 全家桶之 Lightroom Classic
- Unit 3 Friendship and loyalty
- 七月之美:璀璨时光的缤纷绽放
- 云计算演义(1)衣服再漂亮,总是要脱的:一个单词的演变,见证了一个时代的开端...
- javaWeb学习记录:学生信息管理系统
- H5标签<video>安卓端兼容性问题
- 推进中学理化生实验操作考场建设,培养学生的核心素养
- android fragment不执行onResume,onPause
- Numpy、Pandas、Matplot和Seaborn使用(持续更新)