mysql MySQLdb和PyMySQL区别_mysql Python类库对比

来源:这里教程网 时间:2026-02-28 20:47:28 作者:

PyMySQL 能直接替换 MySQLdb 吗?能,但得加一行注册

绝大多数情况下,

PyMySQL
可以 1:1 替换
MySQLdb
,前提是你的代码没调用底层 C 扩展特有的私有属性(比如
_mysql
模块)。但 Python 导入机制默认不会“假装自己是 MySQLdb”,所以直接把
import MySQLdb
换成
import pymysql
会报错。

正确做法是在项目入口(如

__init__.py
或主脚本最顶部)加这行:

import pymysql
pymysql.install_as_MySQLdb()

之后所有原本写

import MySQLdb
的地方都不用改,
MySQLdb.connect()
cursor.execute()
等全部照常运行。

这是 PyMySQL 提供的兼容层,本质是把自身注册进
sys.modules
,骗过 import 系统
不加这行 → 报错
ModuleNotFoundError: No module named 'MySQLdb'
加了但顺序错了(比如写在
import MySQLdb
之后)→ 依然报错,必须前置

为什么现在基本不用 MySQLdb 了?安装失败是常态

MySQLdb
(即
MySQL-python
)在 Python 3.6+ 已彻底不可用,官方早已停止维护。它依赖系统级 MySQL 客户端开发包(如 Linux 的
libmysqlclient-dev
或 Windows 的 Visual Studio + MySQL Connector/C),而这些环境在 CI/CD、Docker、云函数或 macOS M1/M2 上极难配齐。

立即学习“Python免费学习笔记(深入)”;

macOS:
pip install MySQL-python
基本必报
clang: error: unsupported option '-fopenmp'
Docker(alpine):缺
mysql-dev
gcc
,编译失败率 >90%
Windows:需手动下载并指定
mysql_config
路径,多数人卡在这步
Python 3.11+:源码中大量
PyInt_FromLong
等已被移除的 C API,直接编译不过

相比之下,

pymysql
是纯 Python 实现,
pip install pymysql
一次成功,无任何系统依赖。

性能差多少?日常 CRUD 几乎感觉不到

单条查询或插入,

MySQLdb
(实际多指其现代替代品
mysqlclient
)比
PyMySQL
快约 20%,但这个差距只在压测场景下显著。真实业务中,网络延迟、SQL 优化、索引设计的影响远大于驱动本身。

批量写入(
executemany
):两者差距缩至
≤3%
,PyMySQL 的协议解析优化已很成熟
SELECT 10 万行:
3571 vs 3642 ops/s
,差不到 2%,且结果集传输和应用层处理才是瓶颈
如果你用的是 Django 或 SQLAlchemy,ORM 层开销远高于驱动差异,选哪个对 QPS 影响微乎其微

真正该关注的是:PyMySQL 支持

gevent
协程(
pymysql.connections.Connection
是纯 Python 类,可 monkey patch),而
mysqlclient
的 C 扩展无法安全协程化——这点在高并发 I/O 场景反而是决定性优势。

PyMySQL 有哪些隐藏坑?字符集和 autocommit 最容易翻车

PyMySQL 默认行为和 MySQLdb 不完全一致,两个关键点不注意就会出数据异常:

charset
必须显式指定:
charset='utf8mb4'
(不是
utf8
),否则 emoji 或生僻字存成
?
或报错
autocommit
默认为
False
,但很多老代码依赖 MySQLdb 的“连接默认开启 autocommit”行为(其实那是历史 bug),漏设会导致事务卡住、连接池耗尽
不支持
connect_timeout
参数名,要用
connect_timeout
(没错,拼写一样),但部分旧版文档误写成
connection_timeout
,会静默忽略
执行
SELECT
后,必须调用
cursor.fetchall()
.fetchone()
,否则下次
execute()
会报
Commands out of sync
—— 这和 MySQLdb 一致,但新手常忘

推荐初始化连接时固定写法:

import pymysql
pymysql.install_as_MySQLdb()
<p>conn = pymysql.connect(
host='localhost',
user='root',
password='123',
database='test',
charset='utf8mb4',        # 关键
autocommit=True,         # 关键
connect_timeout=10,
read_timeout=10,
write_timeout=10
)

字符集没设对、autocommit 漏关,是线上数据不一致最隐蔽的源头之一,比选错驱动严重得多。

相关推荐