{"id":5310,"library":"marshmallow-union","title":"Marshmallow Union","description":"marshmallow-union provides a `Union` field for Marshmallow schemas, allowing a single field to accept and serialize/deserialize values that conform to one of several specified field types. The library works by trying a list of fields one by one until one succeeds. The current version is 0.1.15.post1, released in June 2020, indicating a maintenance or inactive release cadence.","status":"maintenance","version":"0.1.15.post1","language":"en","source_language":"en","source_url":"https://github.com/adamboche/python-marshmallow-union","tags":["marshmallow","serialization","deserialization","union","schema","validation"],"install":[{"cmd":"pip install marshmallow-union","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for schema definition and serialization/deserialization.","package":"marshmallow"}],"imports":[{"symbol":"Union","correct":"from marshmallow_union import Union"}],"quickstart":{"code":"import marshmallow\nfrom marshmallow import Schema, fields, ValidationError\nfrom marshmallow_union import Union\n\nclass MySchema(Schema):\n    id = fields.Integer(required=True)\n    value = Union(fields=[fields.Integer(), fields.String()], required=True)\n\n# Deserialization (loading)\ndata_int = {'id': 1, 'value': 123}\ndata_str = {'id': 2, 'value': 'hello'}\ndata_invalid = {'id': 3, 'value': []}\n\nschema = MySchema()\n\n# Load an integer value\nloaded_int = schema.load(data_int)\nprint(f\"Loaded Int: {loaded_int}\")\nassert loaded_int == {'id': 1, 'value': 123}\n\n# Load a string value\nloaded_str = schema.load(data_str)\nprint(f\"Loaded String: {loaded_str}\")\nassert loaded_str == {'id': 2, 'value': 'hello'}\n\n# Attempt to load an invalid value\ntry:\n    schema.load(data_invalid)\nexcept ValidationError as e:\n    print(f\"Validation Error: {e.messages}\")\n    assert 'value' in e.messages\n\n# Serialization (dumping)\ndumped_int = schema.dump(loaded_int)\nprint(f\"Dumped Int: {dumped_int}\")\nassert dumped_int == data_int\n\ndumped_str = schema.dump(loaded_str)\nprint(f\"Dumped String: {dumped_str}\")\nassert dumped_str == data_str","lang":"python","description":"This quickstart demonstrates how to define a `Union` field in a Marshmallow schema and perform both deserialization (loading) and serialization (dumping) of data containing either an integer or a string. It also shows how validation errors are raised for unsupported types."},"warnings":[{"fix":"Order your fields carefully, placing more specific or strict types before more general ones. Alternatively, use `marshmallow-polyfield` for explicit type-based dispatch.","message":"The `Union` field deserializes/serializes by trying fields in the order they are provided until one successfully processes the value without raising an error. This can lead to unexpected behavior if an earlier field accepts an unintended type (e.g., `fields.Integer()` might accept a string like '123'). For precise control over type matching, consider using `marshmallow-polyfield` instead.","severity":"gotcha","affected_versions":"<=0.1.15.post1"},{"fix":"Ensure that your data conforms to at least one of the union's candidate fields during serialization, or implement error handling for `ExceptionGroup`.","message":"Starting from version 0.1.12, if all candidate fields within a `Union` fail during serialization, a `marshmallow_union.ExceptionGroup` is raised. Prior versions might have behaved differently, possibly returning `None` or an empty dictionary.","severity":"breaking","affected_versions":">=0.1.12"},{"fix":"For nested schemas, you might need to implement a custom `dump` method or mixin within your nested schemas to ensure they explicitly raise an error if the object type doesn't match, forcing the `Union` to try the next candidate. See GitHub Issue #38 for a suggested `UnionMemberMixin`.","message":"When using `Union` with `Nested` schemas, the serialization process still follows the 'first successful match' logic. If the first nested schema in the `Union` successfully processes *some* part of the input (even if not fully matching the intended type), subsequent nested schemas for other types will not be attempted, potentially leading to incomplete or incorrect dumps (e.g., an empty dictionary for the nested field).","severity":"gotcha","affected_versions":"<=0.1.15.post1"},{"fix":"Pin your `marshmallow` dependency to a compatible version (e.g., `marshmallow<4.0`). Thoroughly test `marshmallow-union` functionality if upgrading `marshmallow` to a major new version.","message":"The library has not been updated since June 2020. This means it may have compatibility issues with newer versions of Marshmallow (e.g., Marshmallow 4.x, released in April 2026), which introduced significant breaking changes in field usage, validation, and serialization behavior.","severity":"gotcha","affected_versions":"Marshmallow >3.x"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}