mongoengine
mongoengine copied to clipboard
InvalidDocument when using EmbeddedDocument primary key and ReferenceField
The mongoengine documentation states that EmbeddedDocuments support being the primary_key
, which is true, but this breaks if you try to create a ReferenceField
pointing to such a document. Consider the following:
import mongoengine as me
from bson import ObjectId
class IdTag(me.EmbeddedDocument):
id = me.ObjectIdField(default=ObjectId)
tag = StringField(default='')
class VersionedDocument(me.Document):
id = me.EmbeddedDocumentField(IdTag, default=IdTag, primary_key=True)
meta = {'abstract': True}
class A(VersionedDocument):
name = me.StringField()
class B(VersionedDocument):
name = me.StringField()
a = me.ReferenceField(A)
> a1 = A(name="a1").save()
> b1 = B(name="b1", a=a1).save()
> B.objects.get().a
This raises an InvalidDocument
exception during dereferencing. Pymongo uses the id
of the dbref directly in a query:
return self[dbref.collection].find_one({"_id": dbref.id}, session=session, **kwargs)
The relevant call in mongoengine is Line 1178 in fields.py
dereferenced_son = ref_cls._get_db().dereference(dbref)
I think this could be universally fixed with
dereferenced_son = ref_cls._get_db().dereference(DBRef(dbref.collection, dbref.id.to_mongo())
Unless dbref.id
is not always a field, in which case a try..except
should work