【问题标题】:How to handle PyMongo/MongoEngine AutoReconnect?如何处理 PyMongo/MongoEngine 自动重新连接?
【发布时间】:2019-03-15 00:51:02
【问题描述】:
当我使用 MongoEngine 在集合中迭代地查询超过 10 万个文档时。它通常以 “pymongo.errors.AutoReconnect: [Errno 54] Connection reset by peer”结束。
我已经检查了 AutoReconnect 的其他答案/解决方案,但我怀疑这些是否与我遇到的情况相同。所以我发布了这个问题。
是否有任何提示可以避免自动重新连接或我可以做些什么来进行诊断?
以下是我收集的一些解决方案:
- 使用 try...catch...
- 使用 c 扩展 (pymongo_has_c())
- 使用第三方库,如 MongoDBProxy
- 设置关键字参数,如 timeout 和 bulk_size(我试过但没用)
【问题讨论】:
标签:
mongodb
pymongo
mongoengine
【解决方案1】:
MongoProxy 不适用于我的 Mongo 引擎开箱即用。到处使用try .. except 很烦人。最后我得到了如此快速的解决方案。希望对您有所帮助。
import logging
from mongoengine import *
class SafeDocumentMixin:
def save_safe(self, *args, **kwargs):
for attempt in range(5):
try:
return self.save(*args, **kwargs)
except pymongo.errors.AutoReconnect as e:
wait_t = 0.5 * pow(2, attempt) # exponential back off
l.warning("PyMongo auto-reconnecting... %s. Waiting %.1f seconds.", str(e), wait_t)
time.sleep(wait_t)
@classmethod
def objects_safe(cls, *args, **kwargs):
for attempt in range(5):
try:
return cls.objects(*args, **kwargs)
except pymongo.errors.AutoReconnect as e:
wait_t = 0.5 * pow(2, attempt) # exponential back off
logging.warning("PyMongo auto-reconnecting... %s. Waiting %.1f seconds.", str(e), wait_t)
time.sleep(wait_t)
class Person(Document, SafeDocumentMixin):
name = StringField()
age = IntField()
这样使用
Person.objects_safe(age='23')
可能更多的解决方案是使用monkey patching,但我更愿意看到我正在调用自定义方法