-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Trying to upgrade from mongoengine==0.10.5
to mongoengine==0.24.2
. I get the following issue in one of the tests.
Traceback:
File "/usr/local/lib/python3.6/dist-packages/mongoengine/fields.py", line 958, in __get__
return super().__get__(instance, owner)
File "/usr/local/lib/python3.6/dist-packages/mongoengine/base/fields.py", line 310, in __get__
ref_values=ref_values, instance=instance, name=self.name, max_depth=1
File "/usr/local/lib/python3.6/dist-packages/mongoengine/base/fields.py", line 281, in _lazy_load_refs
name=name,
File "/usr/local/lib/python3.6/dist-packages/mongoengine/dereference.py", line 102, in __call__
self.object_map = self._fetch_objects(doc_type=doc_type)
File "/usr/local/lib/python3.6/dist-packages/mongoengine/dereference.py", line 197, in _fetch_objects
references = get_db()[collection].find({"_id": {"$in": refs}})
File "/usr/local/lib/python3.6/dist-packages/mongoengine/connection.py", line 380, in get_db
conn = get_connection(alias)
File "/usr/local/lib/python3.6/dist-packages/mongoengine/connection.py", line 282, in get_connection
raise ConnectionFailure(msg)
mongoengine.connection.ConnectionFailure: You have not defined a default connection
MRE:
class FirstDoc(mongoengine.DynamicDocument):
field = mongoengine.StringField(required=True)
meta = {"db_alias": "my_db"}
class SecondDoc(mongoengine.DynamicDocument):
field = mongoengine.ListField(required=True)
meta = {"db_alias": "my_db"}
fd = FirstDoc(field="abc")
fd.save()
sd = SecondDoc(field=[fd])
sd.save()
print(sd.field)
In mongoengine==0.24.2
:
In [20]: sd.to_mongo()
Out[20]: SON([('_id', ObjectId('670e37b84bd9cb6fcd25ded8')), ('field', [DBRef('first_doc', ObjectId('670e37ae4bd9cb6fcd25ded7'))])])
In mongoengine==0.10.5
:
In [9]: sd.to_mongo()
Out[9]: SON([('_id', ObjectId('670e3b86f45b3d002a4850b9')), ('field', [SON([('_cls', 'FirstDoc'), ('_ref', DBRef('first_doc', ObjectId('670e3b86f45b3d00
2a4850b8')))])])])
As visible above, 0.10.5
embeds the DBRef
inside a SON
object, while 0.24.2
stores the DBRef
bare.
RCA:
https://github.com/MongoEngine/mongoengine/blob/v0.24.2/mongoengine/dereference.py
In 0.24.2
DeReference._find_references()
, we enter and add items at line 151 instead of 153, using the collection name instead of the document class as the key in our reference map.
This means that ref_document_cls_exists
is False
in _fetch_objects()
, hence we try to get the references with references = get_db()[collection].find({"_id": {"$in": refs}})
, which results in the aforementioned error.
https://github.com/MongoEngine/mongoengine/blob/v0.10.5/mongoengine/dereference.py
In 0.10.5
DeReference._find_references()
, we enter at line 116 instead of 114, using the document class as the key.
This means that hasattr(collection, 'objects')
is True
in _fetch_objects()
, hence we get the references with references = collection.objects.in_bulk(refs)
, which has access to the "db_alias"
inside the meta
attribute of the document class.
Question
Is this an issue with my document classes or an actual bug in mongoengine
?