Description
When a document is fetched with a projection that excludes required fields, one does not expect to receive a validation error on the required field when the projected document is modified and updated back to the DB.
Under normal circumstances, this works:
Update: I am not sure how I got it to work originally, but regardless of what type any other fields are, required fields still fail validation.
@instance.register
class TestModel(Document):
required_field = fields.StringField(required=True)
optional_field = fields.StringField()
# initial insert into DB
TestModel(required_field='a value', optional_field='another value').commit()
# fetch projection and update
projected_test_model = TestModel.find_one({'required_field': 'a value'}, {'optional_field': 1})
projected_test_model.optional_field = 'updated_value'
projected_test_model.commit()
However, when the document includes a ListField, this kind of update appears to be failing because the required field is missing, even though the required field is not actually involved as part of the update:
@instance.register
class TestModelWithList(Document):
required_field = fields.StringField(required=True)
optional_fields = fields.ListField(fields.StringField())
# initial insert into DB
TestModelWithList(required_field='a value').commit()
# fetch projection and update
projected_test_model = TestModelWithList.find_one({'required_field': 'a value'}, {'optional_fields': 1})
projected_test_model.optional_fields = ['a new list value']
projected_test_model.commit()
This results in a validation error on the required_field despite the fact that it is not involved in the update:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".venv/lib/python3.8/site-packages/umongo/frameworks/pymongo.py", line 111, in commit
self.required_validate()
File ".venv/lib/python3.8/site-packages/umongo/embedded_document.py", line 118, in required_validate
self._data.required_validate()
File ".venv/lib/python3.8/site-packages/umongo/data_proxy.py", line 179, in required_validate
raise ma.ValidationError(errors)
marshmallow.exceptions.ValidationError: {'required_field': ['Missing data for required field.']}
Why should this fail validation when the required field is not needed? I have checked the generated Mongo query, and it appears to be creating an update query that only sets the newly added optional_fields list, as one would expect:
>>> projected_test_model.pk
ObjectId('607a1b6270638a2267962210')
>>> projected_test_model._data.to_mongo(update=True)
{'$set': {'optional_fields': ['a new list value']}}
I would expect this update to work without the unrelated validation failure similar to the first use case that did not involve a ListField.