使用mongomock测试批量Upsert功能时出现意外参数'sort'错误
我遇到过类似的问题,这大概率是mongomock版本与你使用的pymongo版本不兼容导致的。
问题原因分析
你当前使用的mongomock 4.3.0是2023年的旧版本,而pymongo 4.11是2024年发布的较新版本。在pymongo的新版本中,UpdateOne对象内部新增了sort参数的隐式传递逻辑(即便你代码里没显式设置这个参数),但旧版mongomock的BulkOperationBuilder.add_update()方法还没适配这个参数,因此抛出了"unexpected keyword argument 'sort'"的错误。
可行的解决方案
1. 升级mongomock到兼容版本
这是最直接的解决办法。你可以把mongomock升级到最新稳定版(比如当前的4.10.1及以上版本),新版本的mongomock会同步适配pymongo的API变更,自然支持新增的sort参数。
执行升级命令:
pip install --upgrade mongomock
2. 降级pymongo到与mongomock 4.3.0兼容的版本
如果暂时无法升级mongomock,可以查看mongomock 4.3.0的官方文档,找到它兼容的pymongo版本范围。比如mongomock 4.3.0通常适配pymongo 4.2.x~4.6.x区间的版本,你可以降级pymongo到这个范围:
pip install pymongo==4.6.3
3. 替代方案:使用真实MongoDB测试容器
如果不想在版本兼容上耗费精力,也可以用testcontainers-python启动一个真实的MongoDB容器进行测试,完全模拟生产环境的行为,从根源上避免mongomock的API兼容问题。
核心实现思路示例:
from testcontainers.mongodb import MongoDbContainer from pymongo import MongoClient def test_batch_upsert_catalog(): # 启动MongoDB测试容器 with MongoDbContainer("mongo:6.0") as container: client = MongoClient(container.get_connection_url()) # 初始化测试用的collection,执行你的批量upsert测试逻辑 # ...
4. 临时补丁(仅应急使用)
如果以上方法都暂时不可行,你可以给mongomock的BulkOperationBuilder.add_update()方法打个临时补丁,让它自动忽略sort参数。在测试文件的开头添加如下代码:
from mongomock import bulk_operation # 保存原方法 original_add_update = bulk_operation.BulkOperationBuilder.add_update def patched_add_update(self, update, *args, **kwargs): # 移除不被支持的sort参数 kwargs.pop('sort', None) return original_add_update(self, update, *args, **kwargs) # 替换原方法 bulk_operation.BulkOperationBuilder.add_update = patched_add_update
注意:这种方法属于临时hack,可能引入其他潜在问题,不推荐长期使用。
验证解决效果
修改版本或应用补丁后,重新运行测试用例,应该就能正常执行bulk_write的批量upsert操作了。
备注:内容来源于stack exchange,提问作者Alon Barad

