Python操作MySQL时的UTF-8编码问题求助
解决MySQL插入4字节Unicode字符的编码错误问题
首先咱们得先搞清楚你遇到问题的核心原因:
- MySQL里的
utf8字符集其实是utf8mb3,它最多只能处理3字节的Unicode字符,但你要插入的\xF0\x9D\x95\x8B这类是4字节的Unicode字符(属于Unicode补充平面,比如特殊符号、emoji或罕见文字),所以直接插入会触发1366错误。 - 你手动拼接SQL语句+手动转义单引号的写法,不仅容易出错,还存在SQL注入风险,这是非常不推荐的。
- 你之前尝试的
decode操作在Python3里完全无效——因为Python3的str类型本身就是Unicode编码的字符串,只有bytes类型才有decode方法,所以这些操作会直接触发AttributeError。
接下来给你几个可行的解决方案,按优先级排序:
方案1:修改数据库配置+使用参数化查询(最推荐)
这是从根源解决问题的方式,同时还能彻底规避SQL注入风险。
步骤1:修改数据库字段的字符集
把nombre字段的字符集改成支持4字节Unicode的utf8mb4,对应的排序规则改成utf8mb4_spanish_ci:
ALTER TABLE `table` MODIFY COLUMN `nombre` VARCHAR(250) COLLATE utf8mb4_spanish_ci DEFAULT NULL;
(如果你的整个数据库都需要支持4字节字符,也可以把数据库和表的默认字符集一起改成utf8mb4)
步骤2:修改数据库连接参数
把连接的charset从utf8改成utf8mb4:
conexion = mysql.connector.connect( host='200.**.**.**', database='database', user='user', password='password', port=3306, charset='utf8mb4' # 这里修改为utf8mb4 )
步骤3:用参数化查询代替手动拼接SQL
完全不需要手动转义单引号,mysql-connector会自动处理编码和转义逻辑:
# 不需要再手动replace单引号了! query = "INSERT INTO table(field) VALUES(%s)" # 用%s作为占位符 cursor = conexion.cursor() # 把参数放在元组里传给execute,驱动会自动处理编码和转义 cursor.execute(query, (nombre[0:250],)) conexion.commit() cursor.close()
方案2:过滤4字节Unicode字符(临时妥协方案)
如果暂时没法修改数据库配置,你可以先把字符串里的4字节字符过滤掉再插入,不过这个方案会丢失部分特殊字符:
def filter_4byte_chars(s): # 只保留编码后长度<=3字节的字符 return ''.join(c for c in s if len(c.encode('utf-8')) <= 3) nombre = filter_4byte_chars(nombre) # 同样建议用参数化查询,不要手动拼接SQL query = "INSERT INTO table(field) VALUES(%s)" cursor = conexion.cursor() cursor.execute(query, (nombre[0:250],)) conexion.commit() cursor.close()
解释你之前尝试的方案为什么失败
- 方案a里的
str(nombre, 'utf-8'):Python3的str构造函数只有当第一个参数是bytes类型时,才能指定编码参数;如果第一个参数已经是字符串,传编码会直接触发TypeError。 - 方案b和c里的
nombre.decode('utf-8'):Python3的str类型没有decode方法,decode是bytes类型的专属方法,所以会触发AttributeError。
内容的提问来源于stack exchange,提问作者dblanco
相关产品推荐
相关产品推荐

