MongoEngine / MongoEngine/mongoengine
Reference to Abstract Document generates an InvalidDocument
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
Hi,
Regarding #1155, when I query on a object with a instance variable that has a ReferenceField to an abstract document and this field is already populated with one concrete subclass object.
I get an error when Mongoengine tries to run the method "from_son".
The error I get is the following
Invalid data to create a `User` instance.
notifications - type object 'UserNotifications' has no attribute 'id'
Which makes sense because UserNotifications is indeed abstract. The reference field has the ObjectID of a EditorNotifications object.
Here's the entire stack trace in case it helps:
Traceback (most recent call last):
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/utils/decorators.py", line 34, in _wrapper
return bound_func(*args, **kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 22, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/utils/decorators.py", line 30, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/utils/decorators.py", line 34, in _wrapper
return bound_func(*args, **kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/utils/decorators.py", line 110, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/utils/decorators.py", line 30, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "/Users/AfonsoGraca/Unbabel/unbabel/payment/views.py", line 68, in post
if self.form.is_valid():
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/forms/forms.py", line 184, in is_valid
return self.is_bound and not self.errors
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/forms/forms.py", line 176, in errors
self.full_clean()
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/forms/forms.py", line 393, in full_clean
self._clean_form()
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/django/forms/forms.py", line 417, in _clean_form
cleaned_data = self.clean()
File "/Users/AfonsoGraca/Unbabel/unbabel/payment/forms.py", line 22, in clean
last_cash_out = self.editor.get_last_cash_out()
File "/Users/AfonsoGraca/Unbabel/unbabel/users/mongo_models.py", line 1855, in get_last_cash_out
return self.get_transactions().filter(type='Cash Out').first()
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 264, in first
result = queryset[0]
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 161, in __getitem__
return queryset._document._from_son(queryset._cursor[key],
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 1481, in _cursor
self._cursor_obj = self._collection.find(self._query,
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 1515, in _query
self._mongo_query = self._query_obj.to_query(self._document)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/visitor.py", line 89, in to_query
query = self.accept(SimplificationVisitor())
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/visitor.py", line 139, in accept
return visitor.visit_combination(self)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/visitor.py", line 39, in visit_combination
return Q(**self._query_conjunction(queries))
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/queryset/visitor.py", line 59, in _query_conjunction
combined_query.update(copy.deepcopy(query))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 163, in deepcopy
y = copier(x, memo)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 257, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 190, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 336, in _reconstruct
y.__setstate__(state)
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/base/document.py", line 200, in __setstate__
data["_data"] = self.__class__._from_son(data["_data"])._data
File "/Users/AfonsoGraca/.virtualenvs/unbabel/lib/python2.7/site-packages/mongoengine/base/document.py", line 725, in _from_son
raise InvalidDocumentError(msg)
InvalidDocumentError: Invalid data to create a `User` instance.
notifications - type object 'UserNotifications' has no attribute 'id'
Cheers
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 at the _from_son entry point named in the traceback and inspect how a ReferenceField targeting an abstract document resolves a stored ObjectID for a concrete subclass. Reproduce the case with an abstract UserNotifications reference populated by an EditorNotifications object; done means deserialization no longer raises InvalidDocumentError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100