MongoEngine / MongoEngine/mongoengine
dynamicfield with reference value raise 'field not exist' error when query
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
- Environments
python version:3.6.8
mongoengine version:0.15.3. - operation reproduct
from mongoengine import *
class Person(Document):
name=StringField()
class SomeTest(DynamicDocument):
name=StringField()
connect() #suppose a default server
p=Person(name='Jack').save()
t=SomeTest(name='a')
t.person=p
t.save()
SomeTest.objects #this will raise 'field not exist' error
- reason
In 'base/document.py', the '__expand_dynamic_values' function did not construct document
object correctly. It call "cls(**value)" direclty when "is_dict and '_cls' in value". But the test document is saved as something like :
{
"_id" : {
"$oid" : "5dd60794dde73f1a64ddf052"
},
"name" : "a",
"person" : {
"_ref" : {
"$ref" : "person",
"$id" : {
"$oid" : "5dd5fcfadde73f15c4548073"
}
},
"_cls" : "Person"
}
}
When assigned a document object to the dynamic field, it is saved as a dict with keys ['_ref','_cls'], where '_ref' repsenting a DBRef object.
When query the dynamic document, the '__expand_dynamic_values' function trys to construct a document object with 'cls(**{'_ref':...,'_cls':...])', so it raise error as '_ref' is not a field of the cls.
The latest codes of the function still keep same as version 0.15.3.
- suggest
Modify the '__expand_dynamic_values' function as:
# If the value is a dict with '_cls' in it, turn it into a document
is_dict = isinstance(value, dict)
if is_dict and '_cls' in value:
cls = get_document(value['_cls'])
# my patch to consturct document correctly
if '_ref' in value: # and isinstance(value['_ref'],DBRef) ?
return cls.objects(id=value['_ref'].id).first()
# my patch to consturct document correctly
return cls(**value)
The patch works in my environment.
Or modify the assignment process of dynamic field. I have not read the codes, so may have some approaches more better.
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 base/document.py at __expand_dynamic_values and reproduce the failure with the Python example in the issue, focusing on dynamic fields containing a referenced document. Verify how the stored _ref and _cls values should be expanded, then confirm that SomeTest.objects succeeds and returns the referenced Person without a field-not-found error.
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
- 45/100