
本文详解如何使用 python 的 mysql-connector 驱动安全、高效地将 csv 文件数据批量插入 mysql 数据库,重点解决因 sql 占位符误用、事务未提交、首行标题未跳过等导致的插入失败问题。
在 python 中通过 csv 文件向 MySQL 插入数据是常见需求,但初学者常因细节疏忽(如字符串格式化滥用、缺少事务提交、忽略 CSV 表头)而报错。你遇到的 mycursor.execute(…, row) 报错,根本原因在于:错误地在 SQL 语句中手动添加了单引号 ‘,同时又将参数以元组形式传入,导致 MySQL 驱动器无法正确解析参数类型,引发语法或类型不匹配错误。
✅ 正确做法是:使用 %s 占位符(无引号),由驱动器自动处理类型转换与转义;严禁拼接字符串(如 ‘%s’),否则不仅会失败,更会引入 SQL 注入风险。
以下是经过验证的完整、健壮的实现方案:
✅ 推荐写法(安全 + 可维护)
import mysql.connector import csv import os def insert_csv_to_mysql(): csv_path = r"C:dataLEARNINGPYTHONexcelMYSQLtexpertsEMPLOYEES.csv" # 1. 检查文件是否存在 if not os.path.isfile(csv_path): raise FileNotFoundError(f"CSV 文件未找到: {csv_path}") # 2. 建立数据库连接(请替换为你的实际凭证) mydb = mysql.connector.connect( host="localhost", user="root", password="your_password", database="texperts", autocommit=False # 关键:关闭自动提交,手动控制事务 ) mycursor = mydb.cursor() try: with open(csv_path, encoding='utf-8') as f: reader = csv.reader(f) # 3. 跳过表头(第一行) next(reader, None) # 4. 预编译 SQL(提升性能,避免重复解析) sql = """ INSERT intO employee ( emp_id, emp_init, first_name, last_name, email, phone, role_id ) VALUES (%s, %s, %s, %s, %s, %s, %s) """ # 5. 逐行执行插入(生产环境建议改用 executemany 提升性能) for i, row in enumerate(reader, start=1): if len(row) != 7: print(f"警告:第 {i} 行字段数异常(期望 7,实际 {len(row)}),已跳过: {row}") continue mycursor.execute(sql, row) print(f"✓ 已插入第 {i} 条记录: {row}") # 6. 显式提交事务(关键!否则数据不会持久化) mydb.commit() print("✅ 所有记录插入成功,并已提交事务。") except mysql.connector.Error as e: # 7. 出错时回滚,保证数据一致性 mydb.rollback() print(f"❌ 数据库错误: {e}") raise except Exception as e: mydb.rollback() print(f"❌ 未知错误: {e}") raise finally: # 8. 清理资源 mycursor.close() mydb.close() if __name__ == "__main__": insert_csv_to_mysql()
⚠️ 关键注意事项
- 禁止在 SQL 中给 %s 加引号:VALUES(‘%s’,…) 是错误写法;应为 VALUES(%s,…)。MySQL Connector/Python 会自动根据参数类型(int/str/None)进行安全转义。
- 必须调用 mydb.commit():mysql.connector 默认不自动提交,仅 mydb.commit() 或设置 autocommit=True 才能落盘。
- 务必跳过 CSV 表头:使用 next(reader),否则首行字段名(如 “emp_id”)会被当作字符串值插入,导致类型错误或主键冲突。
- 推荐使用 executemany() 批量插入(适用于万级以下数据):
rows = list(reader) # 读取全部(注意内存) next(rows) # 跳过表头 mycursor.executemany(sql, rows) - 字符编码统一:打开 CSV 时显式指定 encoding=’utf-8’,避免中文或特殊字符乱码。
- 邮箱中的 html 标签需清洗:示例 CSV 中的 是反爬邮箱保护格式,真实场景需用正则或 BeautifulSoup 提取纯邮箱地址,否则会插入无效 HTML。
✅ 验证是否成功?
执行后可快速验证:
立即学习“Python免费学习笔记(深入)”;
SELECT * FROM employee ORDER BY emp_id DESC LIMIT 5;
掌握以上要点,你就能稳定、安全地完成 CSV 到 MySQL 的数据导入任务。记住:参数化查询 + 显式事务 + 资源清理 = 可靠数据操作的黄金三角。