问题现象与背景
在使用Python的pymysql库进行数据库操作时,开发者经常遇到以下报错:
AttributeError: 'Cursor' object has no attribute 'stat'
这个错误通常发生在尝试调用cursor.stat()方法获取查询统计信息时。pymysql作为纯Python实现的MySQL客户端库,其API设计存在某些特殊性与MySQL原生驱动不同。
错误根源分析
通过分析pymysql源码和官方文档,我们发现:
- API设计差异:pymysql的Cursor类确实不包含stat方法,这是与MySQLdb库的重要区别
- 历史兼容性问题:部分开发者从MySQLdb迁移到pymysql时,误以为两者API完全兼容
- 文档缺失:官方文档对统计信息获取方式的说明不够明确
5种解决方案对比
方案1:使用info属性替代
cursor.execute("SELECT * FROM users")
print(cursor._last_executed) # 获取最后执行的SQL
print(cursor.rowcount) # 获取影响行数
方案2:解析SHOW PROFILE
cursor.execute("SHOW PROFILE")
result = cursor.fetchall()
for row in result:
print(f"状态: {row['Status']}, 耗时: {row['Duration']}s")
方案3:启用慢查询日志
通过MySQL服务端配置获取详细统计:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0;
方案4:使用性能分析装饰器
from time import time
def query_timer(func):
def wrapper(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
print(f"执行耗时: {time()-start:.4f}s")
return result
return wrapper
方案5:切换为MySQL Connector
如果需要完整的统计功能,可以考虑使用官方驱动:
import mysql.connector
cnx = mysql.connector.connect()
cursor = cnx.cursor()
cursor.stat() # 正常可用
性能优化建议
- 批量操作时使用executemany替代循环execute
- 合理设置prefetch大小平衡内存与性能
- 使用连接池管理数据库连接
- 通过EXPLAIN分析查询执行计划
异常处理最佳实践
建议采用上下文管理器和完整异常捕获:
try:
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM large_table")
# 使用iter分批获取结果
for row in cursor.iter(size=1000):
process(row)
except pymysql.Error as e:
print(f"数据库错误: {e}")
finally:
connection.close()