MongoEngine/mongoengine

InvalidDocument when using EmbeddedDocument primary key and ReferenceField

bloer opened this issue · 0 comments

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