You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用PyMongo insert_many()抛出OperationFailure而非BulkWriteError的原因

问题分析与解决方案

核心原因

你遇到的问题大概率是PyMongo客户端提前校验了文档BSON大小,在请求发送到MongoDB服务器之前就抛出了OperationFailure,而非等到服务器执行批量写入后返回BulkWriteError。

BSON 16MB的大小限制,PyMongo和MongoDB服务器都会做校验:

  • 调用insert_many时,PyMongo会先对每个文档做预校验,如果发现单个文档超出大小,会直接抛出OperationFailure,不会把请求发送到服务器,自然不会触发批量写入的错误逻辑,有效文档也不会被插入。
  • 之前能触发BulkWriteError,可能是当时环境中客户端未开启该预校验,或者文档大小刚好处于客户端校验阈值外但服务器拦截的范围内(这种情况极少)。

验证方式

可以手动计算每个文档的BSON编码大小,确认是否在客户端就被拦截:

import bson

for idx, doc in enumerate(documents):
    try:
        encoded = bson.BSON.encode(doc)
        print(f"文档{idx}大小:{len(encoded)/1024/1024:.2f}MB")
    except bson.errors.InvalidDocument as e:
        print(f"文档{idx}编码失败:{e}")

如果那个20MB的文档在这一步就报错,说明是客户端预校验的问题。

解决办法

  1. 提前过滤超大文档
    先在客户端筛选出符合BSON大小限制的文档,单独处理超大文档:

from pymongo import MongoClient
from pymongo.errors import BulkWriteError, OperationFailure
import bson

MAX_BSON_SIZE = 16 * 1024 * 1024 # 16MB

documents = [
{'x': 'a'},
{'x': 'b' * 20_000_000},
{'x': 'c'}
]

拆分有效和无效文档

valid_docs = []
invalid_docs = []
for doc in documents:
try:
if len(bson.BSON.encode(doc)) <= MAX_BSON_SIZE:
valid_docs.append(doc)
else:
invalid_docs.append(doc)
except Exception:
invalid_docs.append(doc)

with MongoClient("mongodb://localhost:27017/") as client:
collection = client['my_db']['my_collection']
# 插入有效文档
try:
result = collection.insert_many(valid_docs, ordered=False)
print(f"成功插入{len(result.inserted_ids)}个文档")
except BulkWriteError as e:
print(f"批量写入错误:{e.details}")
# 处理无效文档(比如记录日志、拆分存储等)
if invalid_docs:
print(f"发现{len(invalid_docs)}个超出大小限制的文档")

2. **检查MongoDB服务器配置**
   即使未更新版本,Docker容器重启后配置可能变化,查看MongoDB日志(`docker logs <容器名>`),确认是否有关于批量写入的错误日志,排除服务器端异常行为。

3. **确认PyMongo依赖环境**
   即使没更新PyMongo版本,依赖的`bson`库可能被间接更新,执行`pip list | grep bson`查看版本,对比之前能正常复现的环境版本,若有变化可回退旧版本测试。

---
内容的提问来源于stack exchange,提问作者SOCell
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:17:49