copy_from是psycopg2的最快路径,但数据格式需要严格预处理;bulk_insert_mappings跳过ORM实例化,兼顾性能和可控性;to_sql默认行为危险,index必须显式配置、method等参数。
psycopg2 的 copy_from 这是最快的路径,但必须预处理数据格式;SQLAlchemy 的 bulk_insert_mappings 和 pandas.DataFrame.to_sql 这是一种折衷选择,每一种都有明确的适用边界。
用 copy_from 写入 PostgreSQL(最快,但最粗糙)
这是绕过 SQL 实测比较分析层和直写数据文件的底层方法 execute_values 快 2 倍以上。但是,它不验证类型,不触发触发器,不走连接池,错误信息要原始得多。
- 数据必须是制表符分隔,没有 header、
null显式写成空字符串(''),否则会报psycopg2.errors.InvalidTextRepresentation - 字段顺序必须与表定义完全一致,大小写敏感——
copy_from不认列名映射 - 连接需调用
engine.raw_connection(),手动commit(),失败不会自动回滚 - JSON 字段得提前
json.dumps()成字符串,datetime得转成'2026-07-02 04:57:00'格式
bulk_insert_mappings 跳过 ORM 实例化(快速可控)
它直接将字典列表拼成字典列表 INSERT 语句,跳过 User(**d) 构造对象的步骤,CPU 而且内存费用明显下降,但还是走了 SQLAlchemy 连接池和事务管理。
- 不支持
default或server_default,比如'created_at': datetime.now()显式必须插入每个字典 - 超过单次传入 5000 条可能触发 PostgreSQL 上限绑定参数(
too many arguments),建议控制在 1000–3000 条/批 - 如果字段名含有大写字母或特殊字符,例如
"User_Name"),需确保字典 key 与数据库列名严格一致,否则默默丢失字段
to_sql 这似乎很容易,但默认行为是危险的
很多人以为 df.to_sql(..., if_exists='append') 结果上线后发现多了一列 index、字段顺序混乱,或者 MySQL 慢得离谱。
-
index=False必须写上显式,否则 pandas 默认把 DataFrame index 作为一列写进去 - MySQL 默认情况下每行一条
INSERT,加method='multi'可合并为单个多值语句,加速 3–5 倍 - PostgreSQL 下别用
method='multi',不兼容;应重用method=lambda _, df: pg_copy_from(df)配合自定义copy_from - 当列名包含大小写时,
to_sql会报ProgrammingError: (psycopg2.errors.UndefinedColumn),加schema='public'或者可以解决统一的小写列名
再快的写入方法,如果每次写作都建立新的连接,每一个都是 commit,性能仍然崩溃。实际部署时,psycopg2 连接池配置,autocommit=False 手动控制提交时间和批量 size 经验值(通常 1000–2000),比较选择哪一个? API 更关键。
Python 3.14.2
Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。
下载立即学习“Python免费学习笔记(深入);
真正容易被忽视的是:COPY 和 copy_from 不要走连接池,bulk_insert_mappings 和 to_sql 走;一旦用了 to_sql 的 method 自定义函数再次脱离 SQLAlchemy 事务包装-这些边界点根本找不到数据量和错误堆栈。