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使用中碰到的数据库编码问题相关推荐

  1. mysql 查看当前数据库编码方式_MySQL查看与修改当前数据库编码的方法

    MySQL中,数据库的编码是一个相当重要的问题,有时候我们需要查看一下当前数据库的编码,甚至需要修改一下数据库编码. 查看当前数据库编码的SQL语句为: mysql> use xxx Datab ...

  2. mysql 查询编码转换_字符集介绍及mysql数据库编码转换

    一.字符集介绍: 1.ASCII ASCII是英文American Standard Code for Information Interchange的缩写,美国标准信息交换代码是由美国国家标准学会( ...

  3. python读数据-如何用 Python 读取数据?

    原标题:如何用 Python 读取数据? 这是林骥的第 36 篇文章 1. 序言 读取数据往往是做数据分析的第一步,本文没有讲那些艰涩难懂的概念,只有一些问题的解决方案,当你遇到类似的问题的时候,可以 ...

  4. php读取数据显示乱码,php读取数据乱码怎么办

    php读取数据乱码的解决办法:首先将php网页编码设置为"UTF-8":然后连接数据库并插入代码为"$program_char="utf8";mysq ...

  5. 设置MYSQL数据库编码为UTF-8:

    设置mysql数据库显示编码:set charset utf8;  查看mysql数据库编码:show variables like 'character%';    在这个过程中如果出现了数据库编码 ...

  6. python编码与存储读取数据(数组字典)

    Camp时在python2的编码上坑了不少. 理解pyhon2的编码 python2字符串类型只有两种: str类型:b'xxx'即是str类型, 是编码后的类型,len()按字节计算 unicode ...

  7. pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头、pandas使用to_csv函数将dataframe保存为gzip压缩文件

    pandas使用read_csv读取数据使用skiprows参数跳过指定的数据行但保留表头.pandas使用to_csv函数将dataframe保存为gzip压缩文件 目录

  8. python 在excel指定列添加数据_python读取excel指定列数据并写入到新的excel方法

    如下所示: #encoding=utf-8 import xlrd from xlwt import * #------------------读数据------------------------- ...

  9. 如何创建最简单的 ABAP 数据库表,以及编码从数据库表中读取数据 (上) 试读版

    ABAP 标准培训教程 BC400 学习笔记之一:ABAP 服务器的架构和一个典型的 ABAP 程序结构介绍 ABAP 标准培训教程 BC400 学习笔记之二:Cross-client 和 Clien ...

最新文章

  1. CleanMyMac扩展管理功能
  2. MySQL参数优化辅助工具_mysqltuner.pl
  3. [网络安全提高班] 一〇一.网络攻防溯源普及和医疗数据安全总结
  4. [每天一个知识点]3-程序员的三大美德(2)
  5. exxi6.7如何传文件到win7_比QQ直传快100倍!它让PC、安卓、iPhone光速互传文件
  6. 前端学习(3337):ant design中button按钮尺寸size
  7. Mysql字段修饰符(约束)
  8. 为什么PostgreSQL是最先进的开源数据库
  9. 图说:Windows 8 Copy的呈现变化
  10. (扫盲)WebSocket 教程
  11. 微信公众平台开发,图文回复、access_token生成调用、以及微信SDK的实现(2)
  12. 计算机组成原理 笔记 第二版 唐朔飞
  13. protel相关资料
  14. 升级版4850竖曲线
  15. KK课表抓取教务系统
  16. 工作-safari时间格式
  17. 计算机中字符的表示方法
  18. Http请求全过程简述
  19. JS数组转字符串传到JAVA后端取出
  20. 敏捷开发篇--Agile Development-自用

热门文章

  1. java web jsp的银行柜员绩效考核系统
  2. macOS 安装 Adobe 全家桶之 Lightroom Classic
  3. Unit 3 Friendship and loyalty
  4. 七月之美:璀璨时光的缤纷绽放
  5. 云计算演义(1)衣服再漂亮,总是要脱的:一个单词的演变,见证了一个时代的开端...
  6. javaWeb学习记录:学生信息管理系统
  7. H5标签<video>安卓端兼容性问题
  8. 推进中学理化生实验操作考场建设,培养学生的核心素养
  9. android fragment不执行onResume,onPause
  10. Numpy、Pandas、Matplot和Seaborn使用(持续更新)