首页 > 解决方案 > LInux 上 python 3 和 sqlite 的 Unicode 错误

问题描述

我有一个 Python 程序,可以从 SQL 数据库中的数据生成报告。对于 CI 管道测试,我使用以下命令在内存中创建 sqlite3 数据库:

from sqlaclhemy import create_engine
eng = create_engine("sqlite:///")
con = eng.connect()

我从一堆 csv 文件(都是 utf8)初始化这个数据库,文件名作为表名,第一行作为标题。初始化是这样完成的:

import petl as etl
for file in folder:
    filename = os.path.splittext(os.path.basename(os.path.absname(file))[0])
    data = etl.fromcsv(file, delimiter='|', encoding="utf8")
    etl.todb(csvTable, con, filename, create=true)

然后使用此数据库为应用程序运行测试。

所有测试在我的 Windows-10 开发机器上运行良好,但是当我推送到 git 并触发 CI 作业(CI 作业在基于 centos7 的 docker 容器中运行)时,测试失败。经过一些调试后,我设法通过以下代码片段找到了失败的根本原因:

results = etl.fromdb(con, "SELECT * FROM PERSONS")
print(results)

这会导致以下错误:

UnicodeEncodeError:“ascii”编解码器无法在位置 317 编码字符“\xe4”:序数不在范围内(128)

知道是什么原因造成的。sqlalchemy 和 sqlite 都应该默认使用 utf8。为什么我的代码在windows下能用,在linux下不行。我已经尝试解决这个问题一天了,我很难过。任何帮助表示赞赏。

Python 是 3.6.8 版,所有包在我的 windows 和 linux 机器上都是相同的版本。

PS print 命令用于演示问题(测试字体使用 print())。实际问题是,当查询包含 Unicode 字符(本例中为“ä”)的表时,结果为空。

标签: pythonsqliteunicodesqlalchemypetl

解决方案


好的,根据克劳斯的评论,问题是语言环境。我们的 docker 容器没有 localectl 进程,即使在 /etc/locale.conf 中设置了语言环境,系统默认为 POSIX。添加 LANG 环境变量解决了这个问题。


推荐阅读