MongoEngine / MongoEngine/mongoengine
Can not upsert when has field named 'id'
Open
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
When upserting a document, if there's a field named id, error happened.
~/test.py in <module>
11 connect(db='test1', host='127.0.0.1', port=27017)
12
---> 13 A.objects(x=1).upsert_one(id=1)
/usr/local/var/pyenv/versions/3.6.6/envs/one/lib/python3.6/site-packages/mongoengine/queryset/base.py in upsert_one(self, write_concern, **update)
562
563 if atomic_update.raw_result['updatedExisting']:
--> 564 document = self.get()
565 else:
566 document = self._document.objects.with_id(atomic_update.upserted_id)
/usr/local/var/pyenv/versions/3.6.6/envs/one/lib/python3.6/site-packages/mongoengine/queryset/base.py in get(self, *q_objs, **query)
270
271 try:
--> 272 result = next(queryset)
273 except StopIteration:
274 msg = ('%s matching query does not exist.'
/usr/local/var/pyenv/versions/3.6.6/envs/one/lib/python3.6/site-packages/mongoengine/queryset/base.py in __next__(self)
1491 doc = self._document._from_son(
1492 raw_doc, _auto_dereference=self._auto_dereference,
-> 1493 only_fields=self.only_fields)
1494
1495 if self._scalar:
/usr/local/var/pyenv/versions/3.6.6/envs/one/lib/python3.6/site-packages/mongoengine/base/document.py in _from_son(cls, son, _auto_dereference, only_fields, created)
720 data = {k: v for k, v in data.items() if k in cls._fields}
721
--> 722 obj = cls(__auto_convert=False, _created=created, __only_fields=only_fields, **data)
723 obj._changed_fields = changed_fields
724 if not _auto_dereference:
/usr/local/var/pyenv/versions/3.6.6/envs/one/lib/python3.6/site-packages/mongoengine/base/document.py in __init__(self, *args, **values)
76 'The fields "{0}" do not exist on the document "{1}"'
77 ).format(_undefined_fields, self._class_name)
---> 78 raise FieldDoesNotExist(msg)
79
80 if self.STRICT and not self._dynamic:
FieldDoesNotExist: The fields "{'_id'}" do not exist on the document "A"
I guess a field named id should be fine since I see example like
user = User.objects.get(id=user_id)
user.switch_db('archive-db')
user.save()
in the document.
from mongoengine import IntField, Document, connect
class A(Document):
x = IntField()
id = IntField()
connect(db='test1', host='127.0.0.1', port=27017)
A.objects(x=1).upsert_one(id=1) # <A: A object>
A.objects(x=1).upsert_one(id=1) # Error
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
Reproduce the two calls in test.py and start by reading mongoengine/queryset/base.py around upsert_one, then follow the document construction path in mongoengine/base/document.py. Confirm that a document with an id field can be upserted repeatedly without FieldDoesNotExist for _id, and add or run regression coverage for both calls.
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
- 35/100