Jav*_*ish 4 python csv sqlite utf-8 character-encoding
我有一个由外部程序填充的sqlite数据库.我试图用python读取数据.当我尝试读取数据时,出现以下错误:
OperationalError:无法解码为UTF-8
如果我在sqlite管理器中打开数据库并使用内置浏览和搜索查看违规记录中的数据,它看起来很好,但是如果我将表导出为csv,我会注意到违规记录中的字符£已成为£
如果我在python中读取csv,违规记录中的£仍然被读为£,但这不是问题,我可以手动解析它.但是,我需要能够直接从数据库中读取数据,而无需转换为csv的中间步骤.
我已经在线查看了类似问题的一些答案,我到目前为止尝试设置"text_factory = str",我也尝试使用sqlite manager将列的数据类型从TEXT更改为BLOB,但仍然得到错误.
我的下面的代码导致OperationalError:无法解码为UTF-8
conn = sqlite3.connect('test.db')
conn.text_factory = str
curr = conn.cursor()
curr.execute('''SELECT xml_dump FROM hands_1 LIMIT 5000 , 5001''')
row = curr.fetchone()
Run Code Online (Sandbox Code Playgroud)
数据库中5000以上的所有记录都有此字符问题,因此产生错误.
任何帮助赞赏.
Api*_*lis 19
Python试图通过将文本片段(在数据库中存储为字节)转换为python str对象来提供帮助.为了进行这种转换,python必须猜测查询返回的每个字节(或字节组)所代表的字母.默认猜测是一个名为utf-8的编码.显然,这种猜测在你的情况下是错误的.
解决方案是给python一些关于如何从字节到字母(即unicode字符)的映射的提示.你已经接近了这条线
conn.text_factory = str
Run Code Online (Sandbox Code Playgroud)
但是(基于您在上面评论中的回复),因为您使用的是python 3,str它是默认的文本工厂,因此该行不会为您做任何新的事情(请参阅文档).
这一行幕后发生的事情是python尝试使用str函数转换查询返回的字节,类似于:
your_string = str(the_bytes, 'utf-8') # actually uses `conn.text_factory`, not `str`
Run Code Online (Sandbox Code Playgroud)
...但你需要一个'utf-8'的不同编码.由于您无法更改str函数的默认编码,因此您必须以其他方式模仿它.您可以使用名为lambda的一次性无名函数:
conn.text_factory = lambda x: str(x, 'latin1')
Run Code Online (Sandbox Code Playgroud)
现在当数据库将字节传递给python时,python将尝试使用'latin1'方案而不是'utf-8'方案将它们映射到字母.当然,我不知道latin1是否是您数据的正确编码.实际上,你必须尝试一些编码来找到合适的编码.我先尝试以下方法:
'iso-8859-1''utf-16''utf-32''latin1'您可以在此处找到更完整的列表.
另一个选择是简单地让来自数据库的字节保持为字节.这对您来说是否好主意取决于您的应用.您可以通过设置来完成:
conn.text_factory = bytes
Run Code Online (Sandbox Code Playgroud)
如果数据库中的文本实际上主要以 UTF-8 编码,但您仍然看到此错误(无法解码为 UTF-8),则问题可能是一行或多行包含无效的虚假数据UTF-8。默认情况下,Python 的decode()函数在看到这样的文本时会抛出异常。如果您处于这种情况并且想简单地忽略这些错误,您可以设置text_factory如下:
conn = sqlite3.connect('my-database.db')
conn.text_factory = lambda b: b.decode(errors = 'ignore')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9933 次 |
| 最近记录: |