Holmesian Blog

一则Incorrect string value问题

今天被一个python读写mysql的编码问题折腾了好几个小时,一开始还以为是Python3的中文编码的历史遗留问题,但最后发现是MariaDB(即Mysql)的锅。

情况是这样的,有一批GBK编码的网页,用Python3的requests抓下数据后,主要写入代码如下:


    class Contract:
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='zcks', passwd='zcks',db='zcks',charset='utf8')
        cur = conn.cursor()
    
    ...
    
        def muGain(self,q_id):
            sql="INSERT INTO `true` VALUES ('%s', '%s', '%s', '%s' )"%(q_id,q_question,q_answer,q_answerkey)
            try:
                self.cur.execute("SET NAMES 'utf8';")
                self.cur.execute(sql.encode('utf-8'))
                self.conn.commit()
                print("DB updated!")
            except:
                print(sql,'DB Error')
    ...

写入MariaDB时,抛出下列错误:

    Warning: Incorrect string value: '\xEF\xBC\xA1\xE3\x80\x81...' for column 'answer' at row 1

相应的数据库为utf8_unicode_ci编码,控制台字符参数:

    MariaDB [zcks]>  show variables like 'character%' ;
    +--------------------------+--------------------------------+
    | Variable_name            | Value                          |
    +--------------------------+--------------------------------+
    | character_set_client     | utf8                           |
    | character_set_connection | utf8                           |
    | character_set_database   | utf8                           |
    | character_set_filesystem | binary                         |
    | character_set_results    | utf8                           |
    | character_set_server     | utf8                        |
    | character_set_system     | utf8                           |
    | character_sets_dir       | D:\xampp\mysql\share\charsets\ |
    +--------------------------+--------------------------------+
    8 rows in set (0.00 sec)

尝试统一文件、字符串、数据库编码为utf-8,问题依旧。最后通过改为utf8mb4编码解决这个问题,即在my.ini中添加:

    collation-server=utf8mb4_unicode_ci
    character_set_server=utf8mb4

再将数据库,改为utf8mb4_unicode_ci,可爱的中文就可以正常入库了。


关于utf8mb4

MYSQL 5.5.3之前的版本中UTF8编码只支持1-3个字节,utf8mb4使得一个字符最多能有4字节,utf8mb4是utf8的超集。

理论上直接用uft8应该不会产生中文无法入库的问题,现在虽然问题解决了,但是这例只能用utf8mb4才不会乱码的问题我依旧不知道症结在哪,望大神能指教。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »