In do_load you have the following code block:
if errors:
exc = ValidationError(errors, data=data, valid_data=result)
self.handle_error(exc, data, many=many, partial=partial)
raise exc
So the exception is raised unconditionally. This means that there is no way for a custom schema to correct or suppress an error raised by a sub-schema.
Our use case is wanting to have a schema in which some fields are validated, but the remainder are passed "as is" (they are massaged and validated later on in our data pipeline). In Marshmallow 2 we set our schema to strict=False and had our handle_error raise on the fields we wanted validated. As far as I can see there is no equivalent functionality in Marshmallow 3. This could be solved by having the code that calls handle_error allow it to signal that the exception be ignored. For example, it could treat a return value of True from handle_error as signalling that the error has been successfully handled and should not be raised.
(By the way, this use case is similar to that mentioned in #1198, but we aren't serializing an object, just a json data structure. We are currently using a @post_dump method to include the unknown fields in the dump, but I haven't actually gotten far enough yet to know if that will actually work in Marshmallow 3 :)
After thinking about this some more I realize that the actual use case is that we want to log the violations in the other fields, but pass them through. That's the thing we can't do currently with Marshmallow 3, because we can't suppress the errors after we log them. It is quite possible we could do without this logging, though, so I won't be devastated if you reject this feature request :)
Further addendum. We do raise on certain "dirty" field errors, such as a missing required value. I can create a new schema that just has the fields that need to be so checked, with just those minimum checks. The disadvantage of this is that it leads to redundant field definitions: one with partial validation and one with full validation. I can live with that, but it would be nice not to have to :)
Ah, nevermind. What I requested wouldn't do what we wanted because _do_load is called from validate as well.
What I ended up with was adding a 'load' method to our schema that calls super inside a try/except and does what we want. Sorry for wasting your time :(
Ah, nevermind. What I requested wouldn't do what we wanted because _do_load is called from validate as well.
What I ended up with was adding a 'load' method to our schema that calls super inside a try/except and does what we want. Sorry for wasting your time :(
can you show a example on how you did override the load method? I am trying to perform the same.
The validation error that is raised has a valid_data property you can use to recover the valid data.
https://marshmallow.readthedocs.io/en/stable/quickstart.html#validation
I think this is what @bitdancer ended up doing:
```py
from marshmallow import Schema, fields, ValidationError
class Test(Schema):
foo = fields.String()
bar = fields.String()
def load(self, *args, **kwargs):
try:
return super().load(*args, **kwargs)
except ValidationError as e:
return e.valid_data
Test().load({'foo': 123, 'bar': 'ok'})
````
@deckar01 thank you for the sample!
Yes, that's exactly right, although we have certain errors that we check for and still raise. Which gives us a dependency on the text of the error messages that I'd like to eliminate at some point, but it is good enough for now :)
Most helpful comment
The validation error that is raised has a
valid_dataproperty you can use to recover the valid data.https://marshmallow.readthedocs.io/en/stable/quickstart.html#validation
I think this is what @bitdancer ended up doing:
```py
from marshmallow import Schema, fields, ValidationError
class Test(Schema):
foo = fields.String()
bar = fields.String()
Test().load({'foo': 123, 'bar': 'ok'})
{'bar': 'ok'}
````