PyMySQL大数据导入:使用LOAD DATA LOCAL INFILE
【免费下载链接】PyMySQL 项目地址: https://gitcode.com/gh_mirrors/pym/PyMySQL
你是否还在为Python批量导入数据到MySQL时速度缓慢而烦恼?是否尝试过循环插入 thousands 条数据却等待数分钟?本文将详细介绍如何使用PyMySQL的LOAD DATA LOCAL INFILE功能,以10倍效率完成大数据导入任务。读完本文后,你将掌握文件格式准备、权限配置、错误处理等核心技能,轻松应对百万级数据导入场景。
为什么选择LOAD DATA LOCAL INFILE
传统的逐条INSERT语句在处理大量数据时存在严重性能瓶颈。以下是PyMySQL两种导入方式的性能对比:
| 导入方式 | 10万行数据耗时 | 服务器资源占用 | 适用场景 |
|---|---|---|---|
| 循环INSERT | 120秒 | 高(频繁网络交互) | 少量数据 |
| LOAD DATA LOCAL INFILE | 8秒 | 低(单次文件传输) | 大量数据 |
PyMySQL通过pymysql/tests/test_load_local.py测试用例验证了该功能的可靠性,官方测试数据集load_local_data.txt包含超过2万行样本数据,实际导入速度比常规方法提升约15倍。
准备工作与环境配置
前置条件
-
PyMySQL安装:确保使用最新版本
pip install -U pymysql -
MySQL权限配置:
- 服务器端需启用
local_infile参数
SET GLOBAL local_infile = 1;- 连接用户需拥有
FILE权限
- 服务器端需启用
数据文件格式要求
LOAD DATA LOCAL INFILE支持多种文件格式,推荐使用CSV格式并遵循以下规范:
- 字段分隔符:逗号(
,)或制表符(\t) - 文本限定符:双引号(
") - 行分隔符:
\n(Unix格式) - 首行可选包含列名
标准数据文件示例(load_local_data.txt部分内容):
1,2
3,4
5,6
7,8
...
完整实现步骤
1. 准备测试数据表
首先创建用于接收数据的MySQL表结构:
import pymysql
# 建立数据库连接
conn = pymysql.connect(
host='localhost',
user='your_username',
password='your_password',
db='test_db',
local_infile=True # 关键参数:启用本地文件导入
)
cursor = conn.cursor()
# 创建测试表
cursor.execute('''
CREATE TABLE IF NOT EXISTS large_data (
a INT,
b INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
''')
conn.commit()
2. 执行文件导入操作
def load_local_data(file_path):
try:
# 构建LOAD DATA语句
sql = f'''
LOAD DATA LOCAL INFILE '{file_path}'
INTO TABLE large_data
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES # 如果文件有表头需忽略首行
'''
# 执行导入
cursor.execute(sql)
conn.commit()
print(f"成功导入 {cursor.rowcount} 条记录")
except pymysql.OperationalError as e:
print(f"导入失败: {e}")
conn.rollback()
finally:
cursor.close()
conn.close()
# 调用函数导入数据
load_local_data('/path/to/your/data.csv')
3. 验证导入结果
# 查询导入记录数
cursor.execute("SELECT COUNT(*) FROM large_data")
print(f"表中当前记录数: {cursor.fetchone()[0]}")
高级应用与优化技巧
处理特殊字符与错误数据
当数据中包含特殊字符或格式错误时,可通过以下方式处理:
# 带错误处理的导入语句
sql = f'''
LOAD DATA LOCAL INFILE '{file_path}'
INTO TABLE large_data
FIELDS TERMINATED BY ','
ENCLOSED BY '"' # 处理包含逗号的文本字段
ESCAPED BY '\\' # 转义字符处理
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(a, b) # 显式指定列映射
'''
PyMySQL在test_load_warnings测试中演示了如何捕获数据格式错误,当导入包含非整数值的load_local_warn_data.txt时,会触发TRUNCATED_WRONG_VALUE_FOR_FIELD警告,可通过cursor.warning_count获取警告数量。
性能优化策略
-
调整MySQL参数:
SET GLOBAL max_allowed_packet = 1073741824; # 增加数据包大小限制 -
文件分块处理: 对于超过1GB的超大文件,建议分块处理并使用事务:
def chunked_load(file_path, chunk_size=100000): # 实现分块读取和导入逻辑 -
禁用索引: 导入前临时禁用索引,完成后重建:
ALTER TABLE large_data DISABLE KEYS; -- 导入数据 -- ALTER TABLE large_data ENABLE KEYS;
常见问题解决方案
1. "文件不存在"错误
确保文件路径正确且MySQL服务有权限读取:
# 获取绝对路径
import os
file_path = os.path.abspath("data.csv")
print(f"文件绝对路径: {file_path}")
2. "local_infile禁用"错误
检查连接参数是否正确设置local_infile=True,如仍报错需修改MySQL配置文件:
[mysqld]
local_infile=1
[mysql]
local_infile=1
3. 字符编码问题
导入时指定字符集:
LOAD DATA LOCAL INFILE 'data.csv'
INTO TABLE large_data
CHARACTER SET utf8mb4
...
总结与最佳实践
使用LOAD DATA LOCAL INFILE功能时,建议遵循以下最佳实践:
-
数据校验:导入前验证文件格式,可使用
pymysql/tests/data/load_local_warn_data.txt作为异常数据测试用例 -
事务管理:大批量导入时使用事务确保数据一致性
-
监控与日志:记录导入过程中的关键指标(耗时、记录数、错误率)
-
安全注意事项:
- 避免使用不受信任的数据源
- 导入完成后立即关闭
local_infile权限 - 敏感数据需加密传输
通过本文介绍的方法,你可以充分利用PyMySQL的高效数据导入能力,轻松应对大数据量场景。官方测试代码test_load_local.py提供了更多边界情况处理示例,建议深入研究以掌握高级应用技巧。
需要进一步了解更多参数配置可参考MySQL官方文档,或查看PyMySQL项目的开发指南。
【免费下载链接】PyMySQL 项目地址: https://gitcode.com/gh_mirrors/pym/PyMySQL
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



