pd.read_excel()读取Excel时中文列名乱码或变Unnamed,主因是文件编码/格式不规范或第三方软件改写BIFF结构;datetime列报错因Excel浮点存储未归一化;to_sql()慢因默认单条插入,应改用method="multi"或"psycopg2";空值需转None再写入。

pd.read_excel() 读取时中文列名乱码或变成Unnamed
Excel 文件如果用 Excel 保存为 .xls 或 .xlsx 但实际编码/格式不规范,pd.read_excel() 默认不会报错,但列名可能被识别成 Unnamed: 0 或出现方块、问号。这不是 pandas 的 bug,而是底层 openpyxl 或 xlrd(旧版)对文件元信息解析失败。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 优先显式指定引擎:
pd.read_excel("data.xlsx", engine="openpyxl")(.xlsx)或engine="xlrd"(仅 .xls,注意 xlrd>=2.0 不再支持 .xlsx) - 检查文件是否被其他程序(如 WPS、Numbers)另存过——这类软件有时会悄悄改写 BIFF 结构,导致列名丢失;用原生 Excel 重新「另存为」一次通常能修复
- 如果列名已损坏,别急着重命名,先用
df.columns.tolist()看真实值,再用df.rename(columns={...})映射,避免硬编码索引
SQLAlchemy 插入时 datetime 列报错 "ValueError: year is out of range"
Excel 里看起来是“2023/5/1”的单元格,pd.read_excel() 可能把它读成 float(Excel 底层存储为天数偏移),转成 datetime 时若未归一化,就容易溢出(比如读到 45123.0 却误当秒数处理)。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 读取后立刻清洗时间列:
df["date"] = pd.to_datetime(df["date"], errors="coerce"),errors="coerce"会把非法值转为NaT,比默认报错更可控 - 确认数据库字段类型匹配:PostgreSQL 用
DATE或TIMESTAMP,MySQL 用DATE/DATETIME,别用VARCHAR存日期——SQLAlchemy 不会自动转换字符串为日期对象 - 插入前用
df.dtypes检查,确保时间列 dtype 是datetime64[ns],不是object
to_sql() 批量写入慢、卡住、内存爆掉
DataFrame.to_sql() 默认一条一条 INSERT,10 万行可能耗时几分钟,还容易触发数据库连接超时或事务日志膨胀。这不是 SQLAlchemy 慢,是没关对开关。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 必须加
if_exists="append"和index=False(除非你真要写索引列) - 用
method="multi":它会拼成INSERT INTO ... VALUES (...), (...), (...),速度提升 3–5 倍;但注意 MySQL 对单条 SQL 长度有限制(max_allowed_packet),可配合chunksize=1000 - PostgreSQL 用户优先用
method="psycopg2"(需装psycopg2-binary),走 COPY 协议,比multi还快一个数量级 - 别在循环里反复调
to_sql()——每次建连接、析构表元数据,开销远大于写入本身
空值(NaN / NaT)写入数据库时报 "NoneType not allowed" 错误
Excel 里的空单元格经 pd.read_excel() 后变成 numpy.nan 或 pd.NaT,而某些数据库驱动(如较老的 cx_Oracle 或 pymssql)不认这些值,直接抛 TypeError。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 统一用
df = df.where(pd.notna(df), None)把所有nan/nat转成 PythonNone,这是 SQLAlchemy 唯一明确支持的空值表示 - 别依赖
na_values参数——它只影响读取阶段,对已加载的 DataFrame 无效 - 如果目标库是 SQLite,可以跳过这步(它内部兼容
nan),但 PostgreSQL/MySQL/Oracle 必须转
最常被忽略的是 Excel 文件本身的“隐藏状态”:合并单元格、筛选视图、自定义数字格式(比如把 20230501 显示成日期但底层存整数)。这些不会报错,但会让 read_excel 解析出错,且错误不明显。建议迁移前用 df.head().to_dict("records") 快速扫一眼原始值,比盯着 Excel 界面更可靠。

















