dataframe转json推送接口报400,主因是nan、timestamp、numpy.int64等类型不兼容json标准;需先replace({np.nan: none})清洗,并用to_dict(orient="records")转换,分批推送+超时重试+响应体校验确保可靠。

用 requests.post 发送 DataFrame 的 JSON 数据时,为什么接口收不到或报 400?
直接 json.dumps(df.to_dict()) 很容易出错——Pandas 的 NaN、Timestamp、numpy.int64 等类型不被标准 JSON 序列化器支持,会抛 TypeError: Object of type Timestamp is not JSON serializable。
- 必须先用
df.replace({np.nan: None})清洗缺失值,否则NaN传到后端可能变成字符串"NaN"或直接中断序列化 -
df.to_dict(orient="records")是最稳妥的转换方式,比to_json()更可控;orient="split"虽然带索引和列名,但多数 REST API 只要纯 records - 别用
df.to_json(orient="records", date_format="iso")后再json.loads()——多一次解析纯属冗余,且 ISO 时间字符串在某些后端需额外配置才能解析
大批量数据推送时,如何避免内存爆掉或超时?
一次性发几万行,requests.post 会把整个 payload 加载进内存,还可能触发服务端的请求体大小限制(如 Nginx 默认 1MB)或超时(如 Flask 默认 30s)。
- 按行或按块分批:用
np.array_split(df, n_chunks)切分,每块 500–2000 行较稳妥(取决于单行数据大小) - 加
timeout=(3.0, 30.0)——第一个是连接超时,第二个是读取超时,避免卡死 - 加重试逻辑:对
requests.exceptions.ConnectionError和状态码502/503做最多 3 次指数退避重试,别依赖默认无重试行为 - 别用
session就以为自动复用连接——HTTP/1.1 keep-alive 需服务端配合,且长连接闲置超时后仍会断开
如何让推送过程可监控、失败可追溯?
生产环境不能只看 response.status_code == 200 就认为成功——后端可能返回 200 但 body 里写 {"success": false, "reason": "duplicate key"}。
- 始终检查响应体:
resp.json().get("success")或按实际 API 文档约定的字段判断业务成功 - 记录每批次的
df.iloc[start:end]的首尾索引或 ID 列,失败时能快速定位哪几条没发出去 - 用
logging.getLogger(__name__).info(f"Pushed {len(chunk)} rows, status {resp.status_code}"),别只打print() - 对失败批次单独保存为
failed_chunk_20240615_001.parquet,方便人工补推或查问题,别丢数据
要不要用异步(aiohttp)?什么情况下值得切?
同步 requests 在单次推送耗时稳定(比如每次 200ms)、并发数 ≤ 5 时完全够用;盲目上异步反而增加复杂度和调试成本。
- 只有当你要同时推 20+ 个不同 endpoint,或单次请求平均 aiohttp
-
aiohttp.ClientSession必须用async with包裹,且整个调用链得是 async——如果主流程是同步的,硬套 async 会引发事件循环冲突 - 别用
asyncio.run()包一层就当“异步”了——那只是启停一个临时 loop,无法复用连接池,性能不如不用 - 真正省时间的是并发发请求,不是单个请求变快;先确认瓶颈是不是网络等待,而不是 CPU 或序列化
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











