Tortoise ORM is an easy-to-use asyncio ORM (Object Relational Mapper) inspired by Django.
Tortoise ORM was built with relations in mind and admiration for the excellent and popular Django ORM. It’s engraved in its design that you are working not with just tables, you work with relational data.
Python has many existing and mature ORMs, unfortunately they are designed with an opposing paradigm of how I/O gets processed. asyncio is relatively new technology that has a different concurrency model, and the largest change is regarding how I/O is handled.
Features
Clean, familiar python interface
Define your models like so:
Initialise your models and database like so:
And use it like so:
Tutorial
Primary entity of tortoise is tortoise.models.Model. You can start writing models like this:
After you defined all your models, tortoise needs you to init them, in order to create backward relations between models and match your db client with appropriate models.
You can do it like this:
Here we create a connection to a SQLite DB database with the default aiosqlite client and then we discover & initialise models.
generate_schema generates schema on empty database, you shouldn’t run it on every app init, run it just once, maybe out of your main code.
If you are running this in a simple script, you can do:
run_async is a helper function to run simple async Tortoise scripts. If you are running Tortoise ORM as part of a service, please take a look at The Importance of cleaning up
After that you can start using your models:
Aerich
You need to add aerich.models to your Tortoise-ORM config first. Example:
Initialise the config file and migrations location:
If your Tortoise-ORM app is not the default models, you must specify the correct app via --app, e.g. aerich --app other_models init-db.
Format of migrate filename is {version_num}_{datetime}_{name|update}.py.
If aerich guesses you are renaming a column, it will ask Rename {old_column} to {new_column} [True]. You can choose True to rename column without column drop, or choose False to drop the column then create. Note that the latter may lose data.
If you need to manually write migration, you could generate empty file:
Now your db is migrated to latest.
Now your db is rolled back to the specified version.