Say I have a Schema like this:
class MySchema(Schema):
field_1 = Float()
field_2 = Float()
...
field_42 = Float()
Is there a w
The following method works for me.
I've demonstrated it using Marshmallow-SQLAlchemy because I'm not sure something like this is needed for plain Marshmallow anymore -- with version 3.0.0 it's pretty straightforward to programmatically create a schema using from_dict
. But you could certainly use these concepts with plain Marshmallow.
Here, I use Marshmallow-SQLAlchemy to infer most of the schema, and then apply special treatment to a couple of the fields programmatically.
import enum
from marshmallow_enum import EnumField
from marshmallow_sqlalchemy import ModelSchema
from sqlalchemy import Column
from sqlalchemy import Enum
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
BaseResource = declarative_base()
class CustomEnum(enum.Enum):
VALUE_1 = "the first value"
VALUE_2 = "the second value"
class ExampleResource(BaseResource):
__tablename__ = "example_resource"
id = Column(Integer, primary_key=True)
enum_field = Column(Enum(CustomEnum), nullable=False)
title = Column(String)
string_two = Column(String)
def __init__(self, **kwargs):
super(ExampleResource, self).__init__(**kwargs)
def generate_schema(class_, serialization_fields, serialization_fields_excluded):
"""A method for programmatically generating schema.
Args:
class_ (class): the class to generate the schema for
serialization_fields (dict): key-value pairs with the field name and its Marshmallow `Field`
serialization_fields_excluded (tuple): fields to exclude
Returns:
schema (marshmallow.schema.Schema): the generated schema
"""
class MarshmallowBaseSchema(object):
pass
if serialization_fields is not None:
for field, marshmallow_field in serialization_fields.items():
setattr(MarshmallowBaseSchema, field, marshmallow_field)
class MarshmallowSchema(MarshmallowBaseSchema, ModelSchema):
class Meta:
model = class_
exclude = serialization_fields_excluded
return MarshmallowSchema
generated_schema = generate_schema(
class_=ExampleResource,
# I'm using a special package to handle the field `enum_field`
serialization_fields=dict(enum_field=EnumField(CustomEnum, by_value=True, required=True)),
# I'm excluding the field `string_two`
serialization_fields_excluded=("string_two",),
)
example_resource = ExampleResource(
id=1,
enum_field=CustomEnum.VALUE_2,
title="A Title",
string_two="This will be ignored."
)
print(generated_schema().dump(example_resource))
# {'title': 'A Title', 'id': 1, 'enum_field': 'the second value'}
It's necessary to define MarshmallowBaseSchema
as a plain object, add all the fields, and then inherit from that class because the Marshmallow Schema initializes all the fields on init (in particular, _init_fields()
), so this inheritance pattern makes sure all the fields are there at that time.