mysql pandas读取mysql数据方法_mysql数据分析类库

1次阅读

pandas.read_sql()是读取mysql数据的首选方法,需先创建SQLAlchemy引擎,支持参数化查询防注入;read_sql_table()仅适用于无条件全表读取;大数据量应分块处理,优先SQL层聚合。

mysql pandas读取mysql数据方法_mysql数据分析类库

用 pandas.read_sql() 读取 MySQL 数据最直接

绝大多数情况下,pandas.read_sql() 是首选。它底层调用 SQLAlchemy,兼容性好、语法简洁,且能自动推断列类型(如 dateTIMEdatetime64[ns])。

关键前提是先建好 SQLAlchemy 引擎:

from sqlalchemy import create_engine engine = create_engine('mysql+pymysql://user:password@localhost:3306/dbname')

然后读取:

import pandas as pd df = pd.read_sql("SELECT * FROM users WHERE created_at > '2024-01-01'", engine)
  • SQL 语句必须是字符串,不支持参数化查询的占位符(如 %s),要用 params= 参数传入
  • 若 SQL 含变量,推荐用 pd.read_sql("select * FROM t WHERE id = %(id)s", engine, params={'id': 123})
  • 避免直接拼接字符串防 SQL 注入,尤其是用户输入参与查询时

read_sql_table() 只适合整表导出,不支持 WHERE 或 JOIN

pd.read_sql_table() 本质是“把整张表当视图读”,不走 SQL 解析,所以不能加条件、不能关联其他表,也不能用函数或别名。它快,但场景极窄。

适用情形只有:确认要全量加载某张小表,且表结构稳定、无敏感字段。

  • 必须指定 table_namecon(引擎),不能传 SQL 字符串
  • 支持 schema 参数读取非默认 schema 的表,例如 read_sql_table('logs', engine, schema='prod')
  • 如果表有自增主键,可配合 chunksize 分批读,但注意它不会自动按主键排序,需额外加 ORDER BY —— 此时不如直接用 read_sql()

MySQL 连接驱动选 pymysql 还是 mysqlclient?

两者都支持,但行为有差异:pymysqlpython 实现,安装简单(pip install pymysql),windows/macOS 兼容性好;mysqlclient 是 C 扩展,性能略高,但编译依赖多(尤其 macosxcode command line tools)。

连接字符串写法不同:

  • mysql+pymysql://...
  • mysql://...mysql+mysqldb://...mysqlclient 对应协议名是 mysqldb

常见报错 ModuleNotFoundError: No module named 'MySQLdb' 就是因为装了 pymysql 却写了 mysql://——此时要么改协议名为 mysql+pymysql://,要么装 mysqlclient

大数据量读取卡死或内存爆掉怎么办

直接 read_sql("SELECT * FROM huge_table", engine) 容易 OOM。核心思路是分块 + 流式处理,而非一次性加载。

  • chunksize 参数返回迭代器:for chunk in pd.read_sql("SELECT * FROM events", engine, chunksize=10000): process(chunk)
  • 确保 MySQL 服务端允许长连接和大结果集,检查 max_allowed_packetwait_timeout
  • 如果只需聚合结果(如统计 UV),优先在 SQL 层计算:read_sql("SELECT DATE(created_at), count(DISTINCT uid) FROM logs GROUP BY DATE(created_at)", engine),别把原始日志全拉过来
  • 注意 chunksize 不是行数上限,而是每次 fetch 的记录数,实际 chunk 大小还受字段长度影响

真正难处理的是带复杂 JOIN 和子查询的大宽表——这种得靠数据库侧优化索引或物化中间结果,pandas 层没太多办法。

text=ZqhQzanResources