mysql批量导入导出最稳方案是pandas+sqlalchemy:read_sql_query配chunksize流式读取,to_sql配method="multi"加速写入;超百万行优先用load data infile,需服务端启用local_infile、注意文件路径和编码(utf-8-sig)。

批量导入导出 MySQL 数据,用 pandas + sqlalchemy 最稳;别直接用 mysql-connector-python 的 executemany 做大批量导入,容易内存爆掉或超时。
用 pandas.read_sql_query 和 to_sql 导出导入最省心
这是日常开发中最常用、容错性最好的组合。它底层自动处理类型映射、分块写入、事务封装,且支持多种数据库驱动。
-
read_sql_query读取时建议加chunksize参数(比如chunksize=10000),避免一次性加载几百万行进内存 -
to_sql写入时必须设if_exists="replace"或"append",否则默认报错;index=False别漏,否则会多写一列index - 如果表已存在且要清空重写,
if_exists="replace"会先DROP TABLE再重建——注意外键约束会失败,得手动删表或用"truncate"(但sqlalchemy不原生支持,需配合con.execute("TRUNCATE TABLE ...")) - 导出速度慢?试试加
method="multi"参数(仅对 MySQL 有效),能把多条INSERT合并成一条,提升 3–5 倍写入速度
LOAD DATA INFILE 是 MySQL 原生命令,导入快但权限和路径限制多
当数据量超过百万行、且你有服务器文件系统访问权限时,LOAD DATA INFILE 是最快方案,比 Python 层逐行插入快一个数量级。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- MySQL 服务端必须开启
local_infile=1(启动参数或运行时执行SET GLOBAL local_infile = 1) - 客户端连接时要显式启用:创建
engine时加connect_args={"client_flag": CLIENT.MULTI_STATEMENTS},再用con.execute("LOAD DATA INFILE '/path/to/file.csv' ...") - 文件路径是 MySQL 服务端视角的路径,不是你本地脚本所在机器;若要用本地文件,得写
LOAD DATA LOCAL INFILE,但很多托管 MySQL(如阿里云 RDS)禁用该功能 - 字段分隔符、行结束符、是否跳过首行等都得在 SQL 中写清楚,例如:
FIELDS TERMINATED BY ',' LINES TERMINATED BY ' ' IGNORE 1 ROWS
导出 CSV 时中文乱码、时间格式错、NULL 变空字符串?这些参数不能少
pandas.to_csv 默认编码和序列化行为常踩坑,尤其涉及中文和时间类型。
- 导出必须指定
encoding="utf-8-sig",否则 Excel 打开中文是乱码(utf-8不带 BOM,Excel 识别不了) -
date_format="%Y-%m-%d %H:%M:%S"控制datetime列输出格式,否则 pandas 可能转成时间戳或丢掉毫秒 -
na_rep="NULL"让 NaN 在 CSV 中显示为NULL字符串,而不是空字段——否则导入时 MySQL 可能误判为""而非NULL - 如果导出后字段被双引号包围太多,加
quoting=csv.QUOTE_MINIMAL(默认值)或QUOTE_NONE(需同时设escapechar="\ "防冲突)
大表导出卡死、OOM 或连接中断?关键在分块与连接保活
导出千万级表时,常见现象是 Python 进程内存飙升、MySQL 连接超时断开、或磁盘写满临时文件。
- 永远不要用
df = pd.read_sql("SELECT * FROM big_table", con)—— 改用pd.read_sql_query(..., chunksize=N),然后用for chunk in df_iter:流式处理 - MySQL 默认
wait_timeout=28800(8 小时),但云数据库常缩到 300 秒;可在连接 URL 加?charset=utf8mb4&connect_timeout=60&read_timeout=60&write_timeout=60 - 长时间查询记得加
SQL_NO_CACHE(如SELECT SQL_NO_CACHE * FROM ...),避免触发 MySQL 查询缓存锁表 - 如果导出中间失败,记录当前最大
id或时间戳,下次从断点继续,别重头跑
真正难的不是语法,而是面对 500 万行数据时,怎么让内存不涨、连接不断、结果不错——每个环节的参数和边界条件,都得实测验证,不能只抄示例代码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










