State Model
Intro
Think of them as ORM classes but without any particular back-end. They are just classes that define what properties and relationships object can have.
from typing import Optional
from constelite.models import StateModel, Association
class Creature(StateModel):
name: Optional[str]
class Human(Creature):
age: Optional[int]
class Cat(Creature):
owner: Optional[Association[Human]]
def mew(self):
print(f"{self.name} says mew!")
Why Optional ?
Indeed... All fields of StateModel
should be optional to allow exchange of 'partial state models'. Partial states are used when we want to update only certain fields on an object. For example, we might want to only update the name of a cat and not their owner. We would do so by invoking a patch
method of a store:
By allowing partial states we avoid necessity to retrieve an object state from store before editing it. Hence minimizing amount of data we transport over the network.
Model resolution
Let's dump a StateModel
You will notice a model_name
field that we haven't defined in the Cat
state model. This field is generated automatically and takes the value of the state model name.
This is how constelite can resolve serialized objects without explicitly defying what model they should be resolved to. This is particularly useful when we are dealing with subclasses, like Cat(Creature)
.
Let's see how it works