Marshmallow OneOfSchema
marshmallow-oneofschema provides polymorphic schema capabilities for Marshmallow, allowing a single schema to serialize and deserialize objects of different types based on a discriminator field. The current version is 3.2.0, and it follows the release cadence of the core Marshmallow library, with stable and well-tested releases.
Warnings
- breaking marshmallow-oneofschema v2.0.0 and later require Marshmallow v3.x. Attempting to use it with Marshmallow v2.x will result in `ImportError` or other runtime errors due to API changes in Marshmallow.
- breaking The API for defining polymorphic schemas changed significantly in v2.0.0. The `type_map` attribute was removed and replaced by `type_schemas` and `type_field` for clearer definition of type mappings and the discriminator field.
- gotcha Incorrectly specifying or omitting the `type_field` attribute or providing data without this field will lead to deserialization failures (`ValidationError`), as `OneOfSchema` won't know which sub-schema to use.
- gotcha Attempting to serialize or deserialize an object whose type (as indicated by `type_field`) is not present as a key in the `type_schemas` dictionary will result in an error (`ValueError` for dump, `ValidationError` for load).
Install
-
pip install marshmallow-oneofschema
Imports
- OneOfSchema
from marshmallow_oneofschema import OneOfSchema
Quickstart
from marshmallow import Schema, fields
from marshmallow_oneofschema import OneOfSchema
class CatSchema(Schema):
name = fields.String(required=True)
lives = fields.Integer(load_default=9)
class DogSchema(Schema):
name = fields.String(required=True)
breed = fields.String()
class PetSchema(OneOfSchema):
type_schemas = {
"cat": CatSchema,
"dog": DogSchema,
}
type_field = "pet_type" # Discriminator field in input data
# Example data
cat_data = {"pet_type": "cat", "name": "Whiskers", "lives": 7}
dog_data = {"pet_type": "dog", "name": "Buddy", "breed": "Golden Retriever"}
unknown_pet_data = {"pet_type": "fish", "name": "Nemo"}
# Instantiate the polymorphic schema
pet_schema = PetSchema()
# Serialization (dump)
serialized_cat = pet_schema.dump(cat_data)
print(f"Serialized Cat: {serialized_cat}")
serialized_dog = pet_schema.dump(dog_data)
print(f"Serialized Dog: {serialized_dog}")
# Deserialization (load)
loaded_cat = pet_schema.load(serialized_cat)
print(f"Loaded Cat: {loaded_cat}")
loaded_dog = pet_schema.load(serialized_dog)
print(f"Loaded Dog: {loaded_dog}")
try:
# This will raise a ValidationError because 'fish' is not in type_schemas
pet_schema.load(unknown_pet_data)
except Exception as e:
print(f"Error loading unknown type: {e}")