MongoEngine / MongoEngine/mongoengine
InvalidDocument when using EmbeddedDocument primary key and ReferenceField
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in mongoengine/fields.py at line 1178 and reproduce the InvalidDocument with the EmbeddedDocument primary key and ReferenceField example. Compare the dbref handling there with PyMongo's dereference call. Done means B.objects.get().a dereferences successfully without InvalidDocument, with coverage for the reported case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100