MongoEngine / MongoEngine/mongoengine
Support for DictField of ReferenceField with compound primary key
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
Hello,
There seems to be a problem when trying to use a Dictfield of ReferenceFields with a compound key. I have the following snippet:
class Key(me.EmbeddedDocument):
name = me.StringField()
revision = me.IntField()
class B(me.Document):
key = me.EmbeddedDocumentField(Key, primary_key=True)
comment = me.StringField()
class A(me.Document):
description = me.StringField()
b = me.DictField(me.ReferenceField(B, dbref=True))
if __name__ == "__main__":
db = me.connect('Test', host="mongodb://localhost/test")
a = A(description="description")
b = B(comment="comment", key={"name": "name", "revision": 0})
b.save()
a.b["name"] = b
a.save()
b = B.objects().first()
print(b.key.revision)
a = A.objects().first()
print(a.b["name"].key.revision)
Here is the output I get:
0
Traceback (most recent call last):
File ".\debug_instrument.py", line 69, in <module>
print('a.b["name"].key.revision', a.b["name"].key.revision)
File "C:\Users\ezalczer\AppData\Local\Programs\Python\Python37\lib\site-packages\mongoengine\base\fields.py", line 340, in __get__
value = _dereference(value, max_depth=1, instance=instance, name=self.name)
File "C:\Users\ezalczer\AppData\Local\Programs\Python\Python37\lib\site-packages\mongoengine\dereference.py", line 98, in __call__
self.reference_map = self._find_references(items)
File "C:\Users\ezalczer\AppData\Local\Programs\Python\Python37\lib\site-packages\mongoengine\dereference.py", line 153, in _find_references
reference_map.setdefault(item.collection, set()).add(item.id)
TypeError: unhashable type: 'dict'
This issue happens in dereference.py and is caused by the fact that we try to add item.id to a set in reference_map. In this case, item.id is a dictionary, which is not immutable. I'm not sure how to go about that, there should be a way to work around it (for instance convert dict.items to a tuple) but I would like your opinion before I try to implement anything. Or perhaps I am missing something and there is already a way to do that ?
Thanks
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 dereference.py, particularly _find_references, and reproduce the supplied DictField/ReferenceField example with the compound primary key. Trace how item.id is collected in reference_map and verify that dereferencing the stored reference no longer raises the reported TypeError. Done means the example can read a.b["name"].key.revision successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100