Python读取MySQL数据:pymysql与MySQL-connector怎么选?
全面对比 Python 读取 MySQL 数据的主流驱动:pymysql 与 mysql-connector-python。深入分析纯 Python 实现、官方支持、连接池、性能及生态契合度,提供清晰的决策指南与实战代码。
一、PEP 249 与 Python 的 MySQL 驱动体系
在深入代码细节之前,有必要理清 Python 与 MySQL 通信的基础层次。Python 官方通过 PEP 249(Python Database API Specification v2.0)制定了一套通用的数据库操作接口。无论是 PyMySQL 还是 mysql-connector-python,它们对外暴露的顶层接口高度一致:都具备 connect() 函数、Connection 对象、Cursor 游标对象,以及 execute()、fetchall() 等标准方法。
然而,两个库在底层的实现思路与生态定位上存在明显分工。PyMySQL 是纯 Python 编写的开源驱动,与 Python 现代 Web 生态及数据科学工具链配合极其紧密;mysql-connector-python 是 MySQL 官方团队维护的驱动套件,原生集成了更多 MySQL 专有特性与官方安全标准。
二、PyMySQL:社区标准与轻量化首选
PyMySQL 最显著的特征是100% 纯 Python 实现。在早期的 Python 生态中,MySQLdb(底层依赖 C 语言的 mysqlclient)曾是主流,但在 Windows、轻量级 Alpine Docker 镜像或缺少 GCC 开发包的服务器上,C 扩展的编译安装极易报错。PyMySQL 应运而生,彻底摆脱了外部系统库依赖。
1. 安装与基础查询
安装命令简洁直接:
pip install pymysql cryptography
caching_sha2_password 身份验证插件,PyMySQL 需要借助 cryptography 库进行密码加密,因此务必一并安装。
以下是使用 PyMySQL 读取单条与多条数据的经典模板。默认情况下,游标返回元组(tuple),但在实际业务中,我们通常偏好字典形式(dict),方便按字段名索引:
import pymysql
from pymysql.cursors import DictCursor
connection = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='your_password',
database='analytics_db',
charset='utf8mb4',
cursorclass=DictCursor # 返回字典格式数据
)
try:
with connection.cursor() as cursor:
# 参数化查询,防止 SQL 注入
sql = "SELECT id, username, email, created_at FROM users WHERE status = %s LIMIT 10"
cursor.execute(sql, (1,))
# 获取所有读取结果
rows = cursor.fetchall()
for row in rows:
print(f"用户ID: {row['id']}, 用户名: {row['username']}")
finally:
connection.close()
2. 与 Pandas 的天然契合
在数据处理与科学计算中,Pandas 的 read_sql 几乎是每个工程师的标准动作。配合 SQLAlchemy 与 PyMySQL 连接串,能够以极高的人体工学体验完成数据载入:
import pandas as pd
from sqlalchemy import create_engine
# 使用 pymysql 方言
engine = create_engine("mysql+pymysql://root:your_password@127.0.0.1:3306/analytics_db")
df = pd.read_sql("SELECT id, username, score FROM users WHERE score > %s", engine, params=(60,))
print(df.head())
三、mysql-connector-python:官方血统与内置连接池
mysql-connector-python 是 Oracle 官方维护的标准驱动。对于严格遵守企业采购合规、必须采用原厂支持库的场景,它是唯一的官方答案。
1. 安装与读取示例
pip install mysql-connector-python
官方驱动在使用上同样符合 PEP 249 规范,若需要字典格式,通过参数 dictionary=True 即可启用:
import mysql.connector
conn = mysql.connector.connect(
host='127.0.0.1',
port=3306,
user='root',
password='your_password',
database='analytics_db',
charset='utf8mb4'
)
try:
cursor = conn.cursor(dictionary=True)
query = "SELECT id, username, email FROM users WHERE status = %s LIMIT 10"
cursor.execute(query, (1,))
results = cursor.fetchall()
for item in results:
print(f"用户: {item['username']}, 邮箱: {item['email']}")
finally:
cursor.close()
conn.close()
2. 杀手级功能:原生内置连接池
PyMySQL 本身不包含连接池模块。如果编写的是不引入大型 ORM(如 SQLAlchemy)的独立脚本或服务,使用 PyMySQL 就必须额外引入 DBUtils 等第三方连接池。
而 mysql-connector-python 在 mysql.connector.pooling 中自带了完善的连接池机制,即开即用:
from mysql.connector import pooling
db_pool = pooling.MySQLConnectionPool(
pool_name="mypool",
pool_size=5,
host='127.0.0.1',
port=3306,
user='root',
password='your_password',
database='analytics_db'
)
# 从连接池中借出连接
connection = db_pool.get_connection()
try:
cursor = connection.cursor(dictionary=True)
cursor.execute("SELECT COUNT(*) AS total FROM users")
print(cursor.fetchone())
finally:
cursor.close()
connection.close() # 此处 close() 会自动将连接归还至池中
四、数据读取的生命周期与高频避坑点
无论选型哪一个驱动,执行数据读取时都遵循标准生命周期:建立连接、分配游标、执行查询、分批或全量提取、安全释放。在处理千万级或高频查询时,有两点至关重要:
-
坚决避免全量
fetchall()引发 OOM:当数据表体量较大(如几十万行以上)时,fetchall()会将所有行载入 Python 进程内存,极易导致内存撑爆。应改用fetchmany(size)分批获取,或使用流式服务端游标(如 PyMySQL 的SSCursor/SSDictCursor)。 -
禁止字符串拼接 SQL:SQL 注入是读取阶段常见的严重隐患,务必使用
cursor.execute(sql, params)的占位符方式让驱动处理转义。
五、核心维度横向评测
为了全面评估选型影响,我们将两者在工程实际中最关心的五个维度进行系统对比:
性能表现的真实差距
在纯数据读取吞吐方面,纯 Python 模式下的 PyMySQL 与 mysql-connector-python 差异极小(读取瓶颈通常在网络 I/O 与 MySQL 端的索引命中率上,而非驱动本身的 CPU 开销)。如果开启了 mysql-connector-python 的 C 扩展模式(通过安装包含 C 扩展的二进制分发包),解析千万级大数据包时会有约 15%~25% 的 CPU 反序列化提速。然而,对于极度追求极限吞吐的高性能服务,业界通常会直接选择 mysqlclient(完全基于 C 的底层库)或异步池化方案,因此纯驱动之间的微弱性能差异很少成为选型的主导因素。
六、选型决策指南与落地建议
为了帮助你在具体项目中迅速做出决策,以下 4 步决策树给出了条理分明的判断路径:
总结
在实际技术选型中,无需过分纠结微弱的语法差异。PyMySQL 凭借纯 Python、安装无障碍和广泛的社区生态,成为了现代 Web 开发与数据分析的主力军;而 mysql-connector-python 则在官方合规性与原生连接池支持上提供了稳健的保障。根据项目的基础设施环境与架构依赖进行权衡,即可做出最适合工程长效维护的选择。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













