-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OneOfSchema can't use pre/post_dump/load decorators #4
Comments
I will look into this. Meantime, you can implement everything you need in your subschemas (like FooSchema and BarSchema) |
I rechecked source code and I really do not want to dive into all crazy logic that original Schema class has related to pre/post processing, validation and collecting errors. I couldn't find an elegant way to plug into original Schema data dumping/loading pipeline, so I had to replace it's implementation completely thus loosing all pre/post processing. If somebody wants to do pre/post processing regardless of particular payload type, I suggest 1) think twice; 2) implement processing in subtypes: import marshmallow as m
import marshmallow.fields as mf
class FooSchema(m.Schema):
foo = mf.String(required=True)
class BarSchema(m.Schema):
bar = mf.Integer(required=True)
def my_schema_pre_load(schema, data):
# pre process data on load
return data
class MySchema(OneOfSchema):
class MyFooSchema(FooSchema):
pre_load = m.pre_load(my_schema_pre_load)
class MyBarSchema(BarSchema):
pre_load = m.pre_load(my_schema_pre_load)
type_schemas = {
'foo': MyFooSchema,
'bar': MyBarSchema,
} |
Hello, What would you advise in case I want to do preprocessing on type field? For instance I would like to Thanks in advance! |
I was just looking at this because I wanted to add a def _dump(self, obj, **kwargs):
data = super()._dump(obj, **kwargs)
data.pop("type")
return data I bet a similar approach would work for the above case, overriding I looked a bit and I think at this point in time -- with the current codebase and marshmallow3-only support -- we could add these. |
Rather than overriding the `dump()` and `load()` methods of the Schema class, override `_serialize` and `_deserialize`, which are the "concrete" steps in schema loading and dumping which handle loading or dumping on a field-by-field basis. This still uses load() and dump() methods of the type schemas being used, but it happens between the various hooks which may run on the OneOfSchema instance. Add a test that checks that a `post_dump` hook to remove the `type` field works. The most significant downside of this change is that it makes use of several private APIs within marshmallow. Not only are `_serialize` and `_deserialize` private methods, but the error_store object which is used here is also considered private (per marshmallow docs). In order to better guarantee behavior near-identical to marshmallow, several methods from marshmallow.utils have been copied in-tree here. One notable API change here is that arbitrary keyword arguments are no longer being passed from `OneOfSchema.load()` and `OneOfSchema.dump()` down into the type schemas' load and dump methods. As a result, you cannot specify a load or dump parameter here and expect it to take effect. With the switch to overriding `_serialize` and `_deserialize`, there is no practical way to pass parameters like that. closes marshmallow-code#4
Solid workaround, thank you @maximkulkin it would be helpful to explain in the README file that these decorators are not supported |
AFAIU, post_load decorated method is never called. It may be intended, or it may not be an issue, but while trying to do that it failed and I didn't see this documented so I don't know if this is known.
To get this to work, the post_load method needs to be defined in FooSchema and BarSchema (or a common parent).
The text was updated successfully, but these errors were encountered: