Sazzy
Sazzy

Reputation: 1994

Marshmallow nested serialization of a list with base class schema to honour the subclassed schema classes

I am using marshmallow-dataclass to build serializable classes, and nest them under another class in a list.

There is a Base dataclass, which is an abstract class, and has majority of functionality implemented, as well as having @abcmethods. From the base, other dataclasses are created; there will be multiple variations, all subclassed from the Base. Those subclasses work well on their own.

I intend to append all instanced to a Store dataclass under .items. Then be able to have it serialized and deserialized.

Below is a simplified version of what I have:

from abc import ABC, abstractmethod
from typing import List, Tuple
import marshmallow_dataclass
from dataclasses import dataclass

@dataclass
class Base(ABC):
    name: str
    # _klass: str = None

@marshmallow_dataclass.dataclass
class NameAge(Base):
    age: int

@marshmallow_dataclass.dataclass
class NameLocation(Base):
    loc: Tuple[float, float]

@marshmallow_dataclass.dataclass
class Store:
    items: List[Base]

Here is an example of intended use:

a1 = NameAge('John', 33)
a2 = NameLocation('Bob', (50.8, -0.1))

store = Store(items=[a1, a2])

payload = Store.Schema().dump(store)

store_again = Store.Schema().load(payload)

# desired outcome
assert store == store_again

The Problem

What I tried so far

Any suggestions or help will be much appreciated.

Upvotes: 0

Views: 1895

Answers (1)

Epic Wink
Epic Wink

Reputation: 855

Schemas are not inherited: how would the deserialisation know about a class's child classes? Instead use typing.Union:

from abc import ABC, abstractmethod
from typing import List, Tuple, Union

...

@marshmallow_dataclass.dataclass
class Store:
    items: List[Union[NameAge, NameLocation]]

You'll need to install the union extra: pip install marchmallow-dataclass[union]

Upvotes: 1

Related Questions