MongoDB文档超16MB报错但sys.getsizeof显示仅232字节
pymongo操作MongoDB时DocumentTooLarge错误与sys.getsizeof的误区
问题场景
执行pymongo的替换更新操作时触发文档过大错误:
collec.replace_one({"_id": id}, json.loads(json.dumps(data, cls=CustomJSONEncoder)), upsert=True)
错误信息:
{DocumentTooLarge}'update' command document too large
但用sys.getsizeof(json.loads(json.dumps(data, cls=CustomJSONEncoder)))返回值仅232字节,远低于MongoDB单文档16MB限制。后续改用insert_one执行:
collec.insert_one(json.loads(json.dumps(data, cls=CustomJSONEncoder)))
明确触发文档过大错误,但疑惑sys.getsizeof的结果为何失真。
原因分析
sys.getsizeof()的结果不能代表MongoDB实际存储的BSON文档大小:
- 它仅计算Python对象本身的内存占用,不会递归统计嵌套对象(比如嵌套字典、列表内的元素、大字符串等)的总大小
- MongoDB判断文档大小是基于BSON序列化后的字节数,这才是真正受16MB限制的指标,和Python对象的内存占用完全是两个概念
解决建议
- 准确计算BSON文档大小:用pymongo自带的bson模块计算实际序列化后的大小,这才是MongoDB会用到的数值:
import bson doc = json.loads(json.dumps(data, cls=CustomJSONEncoder)) bson_size = len(bson.BSON.encode(doc)) print(f"BSON文档大小:{bson_size / (1024*1024):.2f} MB")
- 定位大字段:检查
data中的嵌套结构、大文本、二进制数据等内容,确认是哪部分导致体积超标 - 处理大文档:如果确实需要存储超过16MB的内容,改用MongoDB的GridFS进行分块存储
内容的提问来源于stack exchange,提问作者mp252
相关产品推荐
相关产品推荐

