When modeling the application logic through Domain Driven Design, you usually need the following object types:
Value object: Any domain object that is uniquely identified by the data it holds, so it has no conceptual identity. They should be treated as immutable. We can still have complex behaviour in value objects. In fact, it's common to support operations, for example, mathematical operators.
Entity: An object that is not defined by it's attributes, but rather by a thread of continuity and it's identity. Unlike values, they have identity equality. We can change their values, and they are still recognizably the same thing.
The Entity class is based on the
BaseModel to enforce that they have the
id_ attribute of type
AnyHttpUrl, used for comparison and hashing of entities.
They also have a private
model_name property with the name of the model.
If you use integer IDs (which is the default), you don't need to define the
id_ at object creation. When you add the entity to the repository, it will
from repository_orm import Entity, load_repository class Author(Entity): first_name: str repo = load_repository() author = Author(first_name="Brandon") # Add entities repo.add(author) repo.commit() # Retrieve entities by their ID brandon = repo.get(0, Author) assert brandon == author # noqa
!!! warning "This will only work with
int ids! For the rest of the cases you
need to give the
Entities have a
merge method that let's you update it's attributes with
the ones of another entity.
from repository_orm import Entity class Author(Entity): name: str is_alive: bool = True author = Author(name="Brandon") # Imagine a complex process here that creates an updated version of the author object new_author = Author(name="New name", is_alive=False) author.merge(new_author) assert author.name == "New name" assert not author.is_alive # Nevertheless the default values are not merged! author.merge(Author(name="Brandon")) assert not author.is_alive # Unless specified by the user author.merge(Author(name="Brandon", is_alive=True)) assert author.is_alive # noqa
For two entities to be mergeable, they need to belong from the same model and
have the same
id_. The previous example worked because by default the
-1 until the entity is added to the repository. If you want to check other
attribute to see if the objects are mergeable, probably that attribute should be
If you don't want to propagate some attributes when merging, add them to the
_skip_on_merge configuration option of the model:
from datetime import datetime from repository_orm import Entity class Author(Entity): name: str is_alive: bool = True birthday: datetime _skip_on_merge = ["birthday"] author = Author(name="Brandon", birthday=datetime(2020, 1, 1)) new_author = Author(name="Brandon", birthday=datetime(1900, 1, 1), is_alive=False) author.merge(new_author) assert author.birthday == datetime(2020, 1, 1) assert not author.is_alive # noqa
It has useful attributes like:
1.9 is released, you need to store the content in the file
_content attribute, to access the content, you can use