Easy async ORM for Python, built with relations in mind
npx @tessl/cli install tessl/pypi-tortoise-orm@0.25.0Easy async ORM for Python, built with relations in mind. Tortoise ORM is an easy-to-use asyncio Object Relational Mapper (ORM) inspired by Django. It provides an intuitive async/await interface for database operations, supporting multiple databases including SQLite, MySQL, PostgreSQL, Microsoft SQL Server, and Oracle.
pip install tortoise-ormfrom tortoise import Tortoise, Model
from tortoise.fields import IntField, CharField, ForeignKeyFieldFor connections:
from tortoise import connectionsFor query building:
from tortoise.queryset import Qfrom tortoise import Tortoise, fields
from tortoise.models import Model
# Define a model
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
email = fields.CharField(max_length=100, unique=True)
class Meta:
table = "users"
# Initialize Tortoise ORM
async def init():
await Tortoise.init(
db_url='sqlite://db.sqlite3',
modules={'models': ['__main__']}
)
# Generate the schema
await Tortoise.generate_schemas()
# Use the model
async def create_user():
user = await User.create(name="Alice", email="alice@example.com")
print(f"Created user: {user.name}")
# Query users
users = await User.all()
user = await User.get(email="alice@example.com")
# Update
user.name = "Alice Smith"
await user.save()
# Delete
await user.delete()
# Clean up
async def close():
await Tortoise.close_connections()Tortoise ORM's design centers around these key components:
This architecture provides Django-like familiarity with async/await support, making it ideal for modern Python web frameworks like FastAPI, Sanic, and Quart.
Model base class and comprehensive field types for defining database schemas, including data fields (IntField, CharField, JSONField, etc.), relational fields (ForeignKeyField, ManyToManyField, OneToOneField), and field options.
class Model:
def __init__(self, **kwargs): ...
async def save(self): ...
async def delete(self): ...
@classmethod
async def create(cls, **kwargs): ...
@classmethod
async def get(cls, **kwargs): ...
@classmethod
async def all(cls): ...Core database management through the Tortoise class, connection handling, schema generation, and database initialization with support for multiple database backends.
class Tortoise:
@classmethod
async def init(cls, config=None, db_url=None, modules=None, **kwargs): ...
@classmethod
async def generate_schemas(cls, safe=True): ...
@classmethod
async def close_connections(cls): ...
@classmethod
def describe_models(cls, models=None, serializable=True): ...Database Operations and Configuration
Advanced query building with QuerySet, Q expressions, filtering, ordering, aggregation, and bulk operations for efficient database access.
class QuerySet:
def filter(self, **kwargs): ...
def exclude(self, **kwargs): ...
def order_by(self, *fields): ...
def limit(self, limit): ...
def offset(self, offset): ...
async def all(self): ...
async def first(self): ...
async def count(self): ...Database function support including text functions (Trim, Length, Lower, Upper), aggregate functions (Count, Sum, Max, Min, Avg), and custom expressions for advanced queries.
class Function:
def __init__(self, *args, **kwargs): ...
def Trim(field): ...
def Length(field): ...
def Count(field="*"): ...
def Sum(field): ...Database Functions and Expressions
Integration utilities for web frameworks including FastAPI, Pydantic model generation, testing utilities, and database-specific extensions for PostgreSQL and MySQL.
# FastAPI integration
def register_tortoise(app, config=None, **kwargs): ...
# Pydantic integration
def pydantic_model_creator(cls, **kwargs): ...Comprehensive exception hierarchy for handling configuration errors, database operational errors, integrity constraints, validation failures, and query-related exceptions.
class BaseORMException(Exception): ...
class ConfigurationError(BaseORMException): ...
class OperationalError(BaseORMException): ...
class IntegrityError(OperationalError): ...
class ValidationError(BaseORMException): ...Model lifecycle event system with decorators for pre/post save and delete signals, enabling custom logic during model operations.
from tortoise.signals import pre_save, post_save, pre_delete, post_delete
@pre_save(User)
async def on_user_pre_save(sender, instance, **kwargs): ...
@post_save(User)
async def on_user_post_save(sender, instance, created, **kwargs): ...Context managers and decorators for database transaction handling, ensuring data consistency across multiple operations.
from tortoise.transactions import in_transaction, atomic
# Context manager
async with in_transaction():
await User.create(name="Alice")
await User.create(name="Bob")
# Decorator
@atomic()
async def create_users():
await User.create(name="Alice")
await User.create(name="Bob")Field validation system with built-in validators for common use cases and support for custom validators.
from tortoise.validators import (
Validator, RegexValidator, MaxLengthValidator,
MinLengthValidator, MinValueValidator, MaxValueValidator
)
class EmailValidator(Validator):
def __call__(self, value): ...Global connection handler for managing database connections.
from tortoise import connections
# Get a connection
connection = connections.get("default")
# Get all connections
all_connections = connections.all()
# Close all connections
await connections.close_all()from tortoise import run_async
def run_async(coro):
"""Simple async runner that cleans up DB connections on exit."""