Components life cycle
When should you create each component?
Bind manager
The SQLAlchemyBindManager
object holds all the SQLAlchemy Engines, which
are supposed to be global objects, therefore it should be created on application
startup and be globally accessible.
From SQLAlchemy documentation:
The Engine is intended to normally be a permanent fixture established up-front and maintained throughout the lifespan of an application.
Repositories
SQLAlchemy documentation
recommends we create Session
object at the beginning of a logical operation where
database access is potentially anticipated.
The repository keeps a Session
object scoped to its lifecycle to avoid unnecessary queries,
and executes a transaction for each operation to maintain isolation. This means you can create
a repository object almost whenever you want, as long as you don't run parallel operations.
The repository is safe in multithreaded applications and in concurrent asyncio tasks, this means
that potentially you can save it in a global variable, and it will have a different Session
in each thread or asyncio task.
Even if the repository can be used with concurrency or parallelism, remember SQLAlchemy models
belong to a single Session
, so sharing the same models in multiple threads or asyncio tasks
will cause problems.
What you can do is:
- Save the repositories in global variables and start a thread / asyncio task to handle a scoped request (e.g. one thread per HTTP request)
What you should not do is:
- Get a list of models
- Save the models using
save()
in parallel threads / tasks (each task will have a different session)
Remember: Concurrent writes to the db can cause undesired scenarios like locks and deadlocks!
The recommendation is to try to use a single repository instance, where possible.
For example a strategy similar to this would be optimal, if possible:
- Create repositories
- Retrieve all the models you need
- Do the changes you need, as per business logic, eventually using multiple threads / tasks
- Save all the changed models as needed
Unit of work
The Unit of Work session management follows the same exact rules as the repository,
therefore you should approach the creation af a UnitOfWork
object in the same way.