簡體   English   中英

在多處理中使用mongoengine-如何關閉mongoengine連接?

[英]Using mongoengine with multiprocessing - how do you close mongoengine connections?

不管我嘗試什么,當嘗試在mongoengine db上使用多處理時,我都會不斷遇到“在fork之前打開MongoClient的警告”,該警告關於未分叉活動的mongo連接。 標准的mongo建議似乎僅是從子進程內部連接到db,但我認為我的工作在功能上應等效,因為我在使用多處理之前關閉了數據庫,但是仍然遇到了問題。

相關的問題或者沒有一個最小的例子或不適用的解決方案是在這里這里 ,具體而言為燒瓶/芹菜和的情況下, 這里

重現該問題的最小示例:

from mongoengine import connect, Document, StringField, ListField, ReferenceField
from pathos.multiprocessing import ProcessingPool


class Base(Document):
    key = StringField(primary_key=True)
    name = StringField()
    parent = ReferenceField('Parent', required=True)

class Parent(Document):
    key = StringField(primary_key=True)
    name = StringField()
    bases = ListField(ReferenceField('Base'))


def remove_base(key):
   db = connect('mydb')
   mongo_b = Base.objects().get(key=key)
   mongo_b.parent.update(pull__bases=mongo_b)
   mongo_b.delete()


### setup
db = connect('mydb', connect=False)

Base(key='b1', name='test', parent='p1').save()
Base(key='b2', name='test', parent='p1').save()
Base(key='b3', name='test2', parent='p1').save()

p=Parent(key='p1', name='parent').save()
p.update(add_to_set__bases='b1')
p.update(add_to_set__bases='b2')
p.update(add_to_set__bases='b3')

### find objects we want to delete
my_base_objects = Base.objects(name='test')
keys = [b.key for b in my_base_objects]
del my_base_objects

# close db to avoid problems?!
db.close()
del db

# parallel map removing base objects and references from the db
# warning generated here
pp = ProcessingPool(2)
pp.map(remove_base, keys)

好的,所以我知道了。 Mongoengine會在各處緩存與數據庫的連接。 如果您手動刪除它們,則此問題已解決。 添加以下導入

from mongoengine import connection

然后添加:

connection._connections = {}
connection._connection_settings ={}
connection._dbs = {}

Base._collection = None
Parent._collection = None

進入“ #close db”部分以解決該問題。

完整的代碼:

from mongoengine import connect, Document, StringField, ListField, ReferenceField, connection
from pathos.multiprocessing import ProcessingPool


class Base(Document):
    key = StringField(primary_key=True)
    name = StringField()
    parent = ReferenceField('Parent', required=True)

class Parent(Document):
    key = StringField(primary_key=True)
    name = StringField()
    bases = ListField(ReferenceField('Base'))


def remove_base(key):
   db = connect('mydb', connect=False)
   mongo_b = Base.objects().get(key=key)
   mongo_b.parent.update(pull__bases=mongo_b)
   mongo_b.delete()

def setup():
    Base(key='b1', name='test', parent='p1').save()
    Base(key='b2', name='test', parent='p1').save()
    Base(key='b3', name='test2', parent='p1').save()

    p=Parent(key='p1', name='parent').save()
    p.update(add_to_set__bases='b1')
    p.update(add_to_set__bases='b2')
    p.update(add_to_set__bases='b3')

db = connect('mydb', connect=False)
setup()
### find objects we want to delete
my_base_objects = Base.objects(name='test')
keys = [b.key for b in my_base_objects]
del my_base_objects


### close db to avoid problems?!
db.close()
db = None

connection._connections = {}
connection._connection_settings ={}
connection._dbs = {}

Base._collection = None
Parent._collection = None

### parallel map removing base objects from the db
pp = ProcessingPool(2)
pp.map(remove_base, keys)

最近得到了改進,從MongoEngine> = 0.18.0開始,應該使用方法connector disconnect()disconnect_all()分別斷開1個或所有現有的連接( changelog 0.18.0

見官方文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM