Python pymysql 连接 MariaDB 10.4 报错 encoding 怎么办?

文章导读
在 PyMySQL 连接参数中显式指定 charset="utf8mb4" 通常能解决 MariaDB 10.4 的编码报错。适用于 PyMySQL 0.9 及以上版本,风险边界是需确保 MariaDB 服务端已启用 utf8mb4 支持。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
A A

在 PyMySQL 连接参数中显式指定 charset="utf8mb4" 通常能解决 MariaDB 10.4 的编码报错。适用于 PyMySQL 0.9 及以上版本,风险边界是需确保 MariaDB 服务端已启用 utf8mb4 支持。

先说结论:绝大多数编码报错源于客户端默认字符集与服务端不一致,显式声明 utf8mb4 可解决。

  • 先确认:检查 MariaDB 服务端默认字符集是否为 utf8mb4。
  • 先处理:在 pymysql.connect 参数中添加 charset="utf8mb4"。
  • 再验证:写入特殊字符(如 Emoji)确认无报错且显示正常。

命令速用版

以下是修正后的 Python 连接代码片段,直接替换原有连接配置:

import pymysql

connection = pymysql.connect(
    host="localhost",
    user="your_user",
    password="your_password",
    database="your_db",
    charset="utf8mb4",  
    use_unicode=True
)

若需检查服务端字符集,登录 MariaDB 执行:

Python pymysql 连接 MariaDB 10.4 报错 encoding 怎么办?
SHOW VARIABLES LIKE 'character_set%';

为什么会这样

根本原因是 PyMySQL 默认字符集与 MariaDB 10.4 服务端默认字符集不匹配。MariaDB 10.4 版本默认推荐使用 utf8mb4 以支持完整 Unicode(包括 Emoji),而旧版 PyMySQL 或默认配置可能使用 utf8 或 latin1,导致写入特殊字符时触发编码错误。

分步处理

按以下顺序操作,每步完成后检查是否有报错:

  1. 检查服务端配置:登录数据库执行 SHOW VARIABLES LIKE 'character_set_server';,确认返回值为 utf8mb4。
  2. 修改连接代码:在 Python 代码的 pymysql.connect() 函数中强制添加 charset="utf8mb4" 参数。
  3. 检查表结构:确保数据库和表的排序规则(Collation)支持 utf8mb4,如 utf8mb4_general_ci
  4. 回滚提醒:若修改后出现乱码,检查历史数据是否原本为 latin1 编码,必要时进行数据转换。

怎么验证是否生效

执行以下操作确认编码修复成功:

Python pymysql 连接 MariaDB 10.4 报错 encoding 怎么办?
  • 写入测试:尝试向数据库插入包含 Emoji 的字符串,如 INSERT INTO test VALUES ('👋');,无报错即为成功。
  • 连接检查:在 Python 中执行 connection.character_set_name(),返回结果应为 utf8mb4。
  • 日志观察:查看应用日志,确认不再出现 pymysql.err.InterfaceError 或编码相关的 Warning。

常见坑

  • utf8 与 utf8mb4 混淆:MySQL/MariaDB 中的 utf8 仅支持 3 字节字符,无法存储 Emoji,必须使用 utf8mb4
  • 旧版本驱动:极旧版本的 PyMySQL 可能对 utf8mb4 支持不佳,建议升级到稳定版本。
  • 配置文件冲突:若 my.cnf 中强制指定了客户端字符集,可能覆盖代码中的设置,需同步检查配置文件。

常见问题

指定 charset 后性能会下降吗?

不会明显下降。字符集转换在现代数据库驱动中开销极小,公开资料中没有看到可靠的量化数据表明会影响业务性能。

如果服务端不支持 utf8mb4 怎么办?

需联系数据库管理员修改服务端配置,或在连接时降级使用 utf8,但将无法存储 Emoji 等特殊字符。

为什么已经设置了 charset 还是报错?

检查数据库表本身的排序规则(Collation)是否兼容,有时表级别设置会覆盖连接级设置。