Repository ORM
Library to persist Pydantic models into different storage backends following the repository pattern.
Installing¶
pip install repository-orm
A Simple Example¶
from repository_orm import Entity, load_repository
class Author(Entity):
first_name: str
last_name: str
country: str
repo = load_repository()
author = Author(first_name="Brandon", last_name="Sanderson", country="US")
# Add entities
repo.add(author)
repo.commit()
# Retrieve entities by their ID
brandon = repo.get(0, Author)
assert brandon == author
# Search entities
brandon = repo.search({"first_name": "Brandon"}, Author)[0]
assert brandon == author
# Delete entities
repo.delete(brandon)
repo.commit()
assert len(repo.all(Author)) == 0
# Close the connection
repo.close()
Repository pattern theory¶
The repository pattern is an abstraction over persistent storage, allowing you to decouple the model layer from the data layer. It hides the boring details of data access by pretending that all of our data is in memory.
It has the following advantages:
- Give a simple interface, which you control, between persistent storage and our domain model.
- It's easy to make a fake version of the repository for unit testing, or to swap out different storage solutions, because the model is fully decoupled from the infrastructure.
- Writing the domain model before thinking about persistence helps focus on the problem at hand. If we need to change our approach, we can do that in our model, without needing to worry about foreign keys or migrations until later.
- Our database schema is simple because we have complete control over how we map our object to tables.
- Speeds up and makes more clean the business logic tests.
- It's easy to implement.
But the following disadvantages:
- An ORM already buys you some decoupling. Changing foreign keys might be hard, but it should be pretty easy to swap between MySQL and PostgreSQL if you ever need to.
- Maintaining ORM mappings by hand requires extra work and extra code.
- An extra layer of abstraction is introduced, and although we may hope it will reduce complexity overall, it does add complexity locally. Furthermore it adds the WTF factor for Python programmers who've never seen this pattern before.
repository-orm aims to mitigate the last ones by:
- Supplying classes that already have the common operations for different storage solutions.
- Supplying test classes and fixtures so extending the provided repositories is easy.
Repositories¶
There are two kinds of repositories:
- Data repositories: Give a common interface to store the models in databases.
- File repositories: Give a common interface to store computer file contents.
Projects using repository-orm
¶
If you want to see the library being used in a simple project, check
pynbox code. Other projects using
repository-orm
are:
- clinv: A DevSecOps command line asset inventory tool.
- pydo: A free software command line task manager built in Python.
If you use the library and want to be listed here, open an issue.
References¶
As most open sourced programs, repository-orm
is standing on the shoulders of
giants, namely:
- pydantic : Used for the Entities definition.
- DeepDiff : Used to search strings in complex objects in the FakeRepository.
- TinyDB : Used to interact with the NoSQL database in the TinyDBRepository
- Pypika : Used to build the SQL queries in the PypikaRepository.
- Yoyo : Used to manage the schema changes of the PypikaRepository.
- Pytest : Testing framework, enhanced by the awesome pytest-cases library that made the parametrization of the tests a lovely experience.
- Mypy : Python static type checker.
- Flakeheaven : Python linter with lots of checks.
- Black : Python formatter to keep a nice style without effort.
- Autoimport : Python formatter to automatically fix wrong import statements.
- isort : Python formatter to order the import statements.
- PDM : Command line tool to manage the dependencies.
- Mkdocs : To build this documentation site, with the Material theme.
- Safety : To check the installed dependencies for known security vulnerabilities.
- Bandit : To finds common security issues in Python code.
- Yamlfix : YAML fixer.
Contributing¶
For guidance on setting up a development environment, and how to make a contribution to repository-orm, see Contributing to repository-orm.
Donations¶
If you are using some of my open-source tools, have enjoyed them, and want to say "thanks", this is a very strong way to do it.
If your product/company depends on these tools, you can sponsor me to ensure I keep happily maintaining them.
If these tools are helping you save money, time, effort, or frustrations; or they are helping you make money, be more productive, efficient, secure, enjoy a bit more your work, or get your product ready faster, this is a great way to show your appreciation. Thanks for that!
And by sponsoring me, you are helping make these tools, that already help you, sustainable and healthy.