通过将4字节unicode插入mysql引发警告

发布于 2021-02-02 16:23:35

请看以下内容:

/home/kinka/workspace/py/tutorial/tutorial/pipelines.py:33: Warning: Incorrect string 
value: '\xF0\x9F\x91\x8A\xF0\x9F...' for column 't_content' at row 1
n = self.cursor.execute(self.sql, (item['topic'], item['url'], item['content']))

该字符串'\xF0\x9F\x91\x8A实际上是一个4字节的unicode
u'\U0001f62a'。mysql的字符集是utf-8,但插入4字节unicode则会截断插入的字符串。我用谷歌搜索了这样的问题,发现5.5.3下的mysql不支持4字节的unicode,不幸的是我的是5.5.224。我不想升级mysql服务器,所以我只想过滤python中的4字节unicode,我尝试使用正则表达式但失败了。那么,有什么帮助吗?

关注者
0
被浏览
74
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    如果MySQL无法处理4字节或更多字节的UTF-8代码,那么您必须过滤掉代码点上的所有unicode字符\U00010000;
    UTF-8将低于该阈值的代码点编码为3个字节或更少。

    您可以为此使用正则表达式:

    >>> import re
    >>> highpoints = re.compile(u'[\U00010000-\U0010ffff]')
    >>> example = u'Some example text with a sleepy face: \U0001f62a'
    >>> highpoints.sub(u'', example)
    u'Some example text with a sleepy face: '
    

    另外,您可以将该.translate()函数与仅包含None值的映射表一起使用:

    >>> nohigh = { i: None for i in xrange(0x10000, 0x110000) }
    >>> example.translate(nohigh)
    u'Some example text with a sleepy face: '
    

    但是,创建转换表将消耗大量内存,并且需要花费一些时间来生成。正则表达式方法效率更高,可能不值得您花精力。

    所有这些都假定您使用的是UCS-4编译的python。如果您的python是使用UCS-2支持编译的,那么您最多只能'\U0000ffff'在正则表达式中使用代码点,而且您永远不会遇到这个问题。

    我注意到从MySQL
    5.5.3开始,新添加的utf8mb4编解码器确实支持完整的Unicode范围。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看