marshmallow-oneofschema
marshmallow-oneofschema copied to clipboard
OneOfSchema can't use pre/post_dump/load decorators
class MyUberSchema(OneOfSchema):
type_schemas = {
'foo': FooSchema,
'bar': BarSchema,
}
@post_load
def whatever(self, data):
print("post load")
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).
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 .lower()
type field value (in order to be able to get the schema whatever case the type is).
Thanks in advance!
I was just looking at this because I wanted to add a post_dump
method to remove the type field. I ended up overloading _dump
as in
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 load
or _load
.
I looked a bit and I think at this point in time -- with the current codebase and marshmallow3-only support -- we could add these. I probably don't have time to work on this soon, but if it sits for a while I might come back with a PR.
I was just looking at this because I wanted to add a
post_dump
method to remove the type field. I ended up overloading_dump
as indef _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
load
or_load
.I looked a bit and I think at this point in time -- with the current codebase and marshmallow3-only support -- we could add these. I probably don't have time to work on this soon, but if it sits for a while I might come back with a PR.
Solid workaround, thank you
@maximkulkin it would be helpful to explain in the README file that these decorators are not supported