如何处理PyMongo / MongoEngine自动重新连接?

时间:2018-10-10 07:14:44

标签: mongodb pymongo mongoengine

当我使用MongoEngine在集合中迭代查询超过100K文档时。通常以“ pymongo.errors.AutoReconnect:[Errno 54]对等重置连接”结束。

我已经检查了有关自动重新连接的其他答案/解决方案,但我怀疑这些情况是否与我遇到的情况相同。所以我发布了这个问题。

有没有避免自动重新连接的提示,或者我可以做些什么来诊断?

以下是我收集的一些解决方案:

  1. 使用try ... catch ...
  2. 使用c扩展名(pymongo_has_c())
  3. 使用MongoDBProxy之类的第三方库
  4. 设置超时时间和bulk_size之类的关键字参数(我尝试过,但是没有用)

1 个答案:

答案 0 :(得分:0)

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,但我更喜欢看到自己正在调用自定义方法