用 pandas.read_csv() 读取 CSV 更稳,它自动处理编码、引号嵌套、空值和类型推断;配合 to_sql() 批量插入可大幅提升效率,但需注意字段对齐、类型预处理和前置校验。

用 pandas.read_csv() 读取 CSV 更稳,别手写 csv.reader
直接用标准库 csv 模块逐行解析容易踩编码、引号嵌套、空值、类型推断的坑。比如遇到 "123,456" 这种带逗号的字段,csv.reader 不设 quoting=csv.QUOTE_MINIMAL 就会切错;再比如中文路径或 BOM 头,不指定 encoding='utf-8-sig' 就报 UnicodeDecodeError。pandas.read_csv() 默认处理这些细节,还能自动识别列类型(int64、datetime64 等),后续插库时少转换。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 始终传
encoding='utf-8-sig',兼容 Windows 记事本保存的 CSV - 加
dtype=str强制全转字符串,避免 pandas 把带前导零的 ID(如"00123")误判成 int 后截断 - 用
na_values=['', 'NULL', 'N/A']统一空值标识,否则数据库可能插进空字符串而非NULL - 示例:
df = pd.read_csv('data.csv', encoding='utf-8-sig', dtype=str, na_values=['', 'NULL'])用
sqlalchemy的to_sql()批量插入,别循环execute()逐行
cursor.execute("INSERT ...", row)插一万条可能要几十秒;而df.to_sql(..., if_exists='append', index=False)底层调用 PostgreSQL 的COPY协议(需psycopg2支持),通常 1 秒内搞定。但默认不走COPY,得手动配method='multi'或用pgcopy扩展。实操建议:
立即学习“Python免费学习笔记(深入)”;
- 连接串里必须含
postgresql+psycopg2://,不能只用postgresql://,否则to_sql退化为单条 INSERT - 加
chunksize=1000防内存溢出,尤其 CSV 超 10 万行时 - 表名用双引号包裹(如
"user_log"),避免 PostgreSQL 关键字冲突(如order、group) - 示例:
engine = create_engine('postgresql+psycopg2://user:pass@localhost:5432/db')<br>df.to_sql('my_table', engine, if_exists='append', index=False, chunksize=1000)字段名和数据类型必须提前对齐 PostgreSQL 表结构
to_sql()默认按 DataFrame 列名建表,但生产环境几乎都要求复用已有表。如果 CSV 列名含空格、大写字母或特殊符号(如"User ID"),PostgreSQL 会自动转小写且丢空格,变成user_id—— 但你的目标表可能是"User ID"(带双引号的标识符),这时直接插会报Column not found。实操建议:
立即学习“Python免费学习笔记(深入)”;
- 先查目标表结构:
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'my_table'; - 用
df.columns = ['col1', 'col2']显式重命名,确保和目标表列名(大小写、下划线)完全一致 - 用
df[col] = pd.to_datetime(df[col])或df[col] = df[col].astype(float)提前转类型,避免 PostgreSQL 因类型不匹配拒绝插入(如把字符串'2023-01-01'插DATE字段时报错) - 空值列若对应
NOT NULL字段,必须提前填默认值,否则插库失败
批量插入失败时,错误定位比重试更重要
常见报错如
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(10),说明某字段超长;或psycopg2.errors.NotNullViolation: null value in column "id" violates not-null constraint,说明有空值漏处理。但to_sql()报错后整批回滚,你根本不知道是第几行出问题。实操建议:
立即学习“Python免费学习笔记(深入)”;
- 插之前加校验:
df['name'].str.len().max() <= 50检查长度,df['id'].isnull().sum()统计空值 - 用
df.iloc[:1000].to_sql(...)先试跑小批量,确认无误再全量 - 真要查具体哪行错,改用
psycopg2.extras.execute_batch(cursor, sql, data_list),它支持page_size分页,并在异常时抛出当前批次索引
字段映射、类型预处理、错误前置校验——这三步漏掉任何一环,批量插入看着快,实际调试花的时间远超手写循环。
- 先查目标表结构:
- 连接串里必须含


















