Update: The real problem is that MySQL utf8 does not support four-byte UTF-8 characters.
There are several questions on this topic, but none of them seems to be my question exactly, except for maybe this one,接受的答案对我不起作用。
我使用MySQLdb
模块在Python中编码,我想将一些文本放入MySQL数据库中。数据库配置为UTF-8,但文本偶尔包含非UTF-8 四字节-UTF-8字符。
数据库修改的Python代码如下所示:
connection = MySQLdb.connect(
'localhost',
'root',
'',
'mydatabase',
charset='utf8',
use_unicode=True)
cursor = connection.cursor()
cursor.execute(
'update mytable set entryContent=%s where entryName=%s',
(entryContent, entryName))
connection.commit()
目前它产生了这个警告:
./myapp.py:233: Warning: Invalid utf8 character string: 'F09286'
(entry, word))
./myapp.py:233: Warning: Incorrect string value: '\xF0\x92\x86\xB7\xF0\x92...' for column 'entry' at row 1
(entryname, entrycontent))
当我查看使用mysql
命令行客户端实际进入数据库的内容时,我看到在第一次出现非UTF-8 四时截断的内容-byte UTF-8字符。
我不在乎保留非UTF-8 四字节UTF-8字符,所以我想做的就是替换所有非UTF-8 四字节UTF-8字符和一些其他有效的UTF-8字符,因此我可以将文本放入数据库。
答案 0 :(得分:3)
原来问题是不我正在向MySQL提供非UTF-8 字符,但我正在提供四字节UTF-8 字符到MySQL时,它只支持三个(和更少)字节UTF-8字符(according to this documentation)
此解决方案保留所有支持的UTF-8字符,并将不支持的UTF-8字符转换为“?”:
>>> print ''.join([c if len(c.encode('utf-8')) < 4 else '?' for c in u'Cognates include Hittite (lāman)'])
Cognates include Hittite ???? (lāman)
我可以将此字符串放入MySQL中,而不会出现上述警告(以及不合需要的截断)。
答案 1 :(得分:3)
您需要将表格编码设置为utf8mb4
以支持4字节UTF-8编码 - https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
此外,MySQL驱动程序支持Unicode字符串,因此您应该传递Unicode以从编码细节中释放您的代码:
E.g。
cursor.execute(u'update mytable set entryContent=%s where entryName=%s',
(entryContent.decode("utf-8"), entryName.decode("utf-8")))
理想情况下,entryContent
和entryName
在您第一次收到代码时会先在代码中解码为Unicode。例如。打开文件或从网络接收时。
答案 2 :(得分:1)
您可以使用正则表达式删除非ascii字符吗?在评论中使用您的示例:
>>> entry = 'Cognates include Hittite (lāman)'
>>> entry = ''.join([char if ord(char) < 128 else '' for char in entry])
>>> print entry
Cognates include Hittite (lman)
这是this answer与其他问题的轻微变化。