Tortoise-ORM – асинхронная ORM

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

Всё больше Python-разработчиков переходит на асинхронную архитектуру приложений. Это особенно актуально для веб-фреймворков вроде FastAPI, где высокая производительность достигается за счёт async/await. Однако большинство традиционных ORM не поддерживают асинхронность. Именно здесь появляется Tortoise-ORM – асинхронная ORM, созданная для нативной поддержки async операций с базами данных.

Tortoise-ORM вдохновлена Django ORM, проста в освоении, и предлагает мощный инструментарий для построения современных приложений.

Основы работы ORM и особенности Tortoise

Что такое ORM и зачем асинхронность

ORM (Object-Relational Mapping) позволяет разработчику описывать таблицы базы данных как Python-классы. Асинхронность в ORM означает возможность неблокирующей работы с базой данных, что критично для масштабируемых API.

Где использовать Tortoise-ORM

  • В FastAPI или других ASGI-приложениях

  • В микросервисах с высокой нагрузкой

  • В любом проекте, где важна асинхронность и производительность

Установка и настройка

bash
pip install tortoise-orm

Создаём файл models.py и определяем модель:

python
from tortoise import fields from tortoise.models import Model class Author(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=100) birth_date = fields.DateField(null=True)

Инициализация в основном скрипте:

python
from tortoise import Tortoise await Tortoise.init( db_url='sqlite://db.sqlite3', modules={'models': ['models']} ) await Tortoise.generate_schemas()

Создание моделей в Tortoise-ORM

  • IntField, CharField, BooleanField, DatetimeField

  • ForeignKeyField — для связей один-ко-многим

  • ManyToManyField, OneToOneField — поддержка всех типов связей

Пример связи:

python
class Book(Model): id = fields.IntField(pk=True) title = fields.CharField(max_length=200) author = fields.ForeignKeyField('models.Author', related_name='books')

Асинхронные операции с базой данных

  • Создание записи:

python
await Author.create(name='Фёдор Достоевский')
  • Чтение:

python
author = await Author.get(name='Фёдор Достоевский')
  • Обновление:

python
author.name = 'Ф. М. Достоевский' await author.save()
  • Удаление:

python
await author.delete()
  • Фильтрация:

python
books = await Book.filter(title__contains='Преступление')

Отношения между моделями

Tortoise поддерживает все типы связей, включая ForeignKey, OneToOne, ManyToMany. Связанные объекты можно получить с помощью await:

python
book = await Book.get(id=1) author = await book.author

Миграции и генерация схемы

Tortoise сам по себе не включает систему миграций, но используется сторонний инструмент aerich:

bash
pip install aerich aerich init -t settings.TORTOISE_ORM

Создание и применение миграций:

bash
aerich init-db aerich migrate aerich upgrade

Интеграция с FastAPI

Tortoise легко подключается к FastAPI с помощью middleware и dependency:

python
from tortoise.contrib.fastapi import register_tortoise register_tortoise( app, db_url='sqlite://db.sqlite3', modules={'models': ['models']}, generate_schemas=True, add_exception_handlers=True, )

Поддерживаемые СУБД

  • SQLite

  • PostgreSQL

  • MySQL

Каждая база имеет свои особенности, но синтаксис Tortoise-ORM остаётся одинаковым.

Тестирование с Tortoise-ORM

Асинхронное тестирование выполняется с использованием pytest-asyncio. Для изоляции удобно использовать SQLite in-memory:

python
db_url = 'sqlite://:memory:'

Производительность и оптимизация

  • select_related — подгрузка ForeignKey

  • prefetch_related — подгрузка ManyToMany и reverse ForeignKey

python
authors = await Author.all().prefetch_related('books')
  • Поддержка транзакций:

python
from tortoise.transactions import in_transaction async with in_transaction(): ...

Сравнение с другими ORM

ORM Асинхронность Простота Поддержка миграций Подходит для
Tortoise-ORM Да Высокая Через aerich API, FastAPI, ASGI
SQLAlchemy Async Да Средняя Alembic Крупные проекты
Peewee + async Частично Высокая peewee-migrate Простые проекты

Поддержка, документация и сообщество

  • Официальный сайт: https://tortoise-orm.readthedocs.io

  • Проект активно развивается

  • Хорошая документация и примеры интеграции

Часто задаваемые вопросы (FAQ)

1. Что такое Tortoise-ORM?
Асинхронная ORM-библиотека для Python, вдохновлённая Django ORM.

2. Поддерживает ли Tortoise-ORM PostgreSQL?
Да, полностью. Также поддерживаются SQLite и MySQL.

3. Как выполнять миграции?
С помощью стороннего инструмента aerich.

4. Подходит ли Tortoise-ORM для продакшена?
Да, при правильной настройке она надёжна и производительна.

5. Есть ли поддержка Pydantic?
Да, можно использовать Pydantic-схемы для валидации данных в FastAPI.

6. Как работать с транзакциями?
С помощью контекстного менеджера in_transaction().

Полный справочник по работе с Tortoise ORM для Python

Установка

bash
pip install tortoise-orm

Для работы с PostgreSQL:

bash
pip install asyncpg

Для SQLite:

bash
pip install aiosqlite

Основные особенности

Возможность Описание
Поддержка asyncio Полностью асинхронный ORM.
Поддержка SQLite, PostgreSQL, MySQL Через async-драйверы.
Стиль, похожий на Django ORM Классы моделей, filter(), all(), get().
Автоматическая генерация схем Создание таблиц из моделей.
Простая интеграция с FastAPI, Starlette и др.  

Пример минимального приложения

python
from tortoise import fields, Tortoise, run_async from tortoise.models import Model class User(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=50) is_active = fields.BooleanField(default=True) async def run(): await Tortoise.init( db_url='sqlite://db.sqlite3', modules={'models': ['__main__']} ) await Tortoise.generate_schemas() user = await User.create(name="Alice") print(await User.all()) run_async(run())

Определение моделей

python
from tortoise.models import Model from tortoise import fields class Author(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=100) class Book(Model): id = fields.IntField(pk=True) title = fields.CharField(max_length=200) author = fields.ForeignKeyField("models.Author", related_name="books") published = fields.DateField()

Основные методы ORM

Метод Описание
Model.create(...) Создание объекта.
Model.get(...) Получение одной записи (исключение при отсутствии).
Model.filter(...) Фильтрация.
Model.all() Все записи.
Model.first() / last() Первая / последняя запись.
Model.update_from_dict() Обновление полей.
Model.delete() Удаление записи.
Model.exists() Проверка наличия.

Примеры запросов

python
# Создание user = await User.create(name="Bob") # Получение user = await User.get(id=1) # Фильтрация users = await User.filter(name__icontains="bo") # Обновление user.name = "Bobby" await user.save() # Удаление await user.delete()

Работа со связями

python
author = await Author.create(name="Толстой") book = await Book.create(title="Война и мир", author=author) # Получение книг автора books = await author.books.all()

Prefetch и select_related

Метод Описание
select_related() Жадная загрузка внешнего ключа (FK).
prefetch_related() Жадная загрузка M2M или reverse FK.
python
# Получить книги с авторами (join) books = await Book.all().select_related('author') # Получить авторов с их книгами (отдельным запросом) authors = await Author.all().prefetch_related('books')

Работа с Pydantic (FastAPI)

bash
pip install tortoise-orm[asyncpg] pydantic
python
from tortoise.contrib.pydantic import pydantic_model_creator User_Pydantic = pydantic_model_creator(User)

Миграции (Tortoise не использует Alembic)

Для автоматической генерации таблиц:

python
await Tortoise.generate_schemas()

Для более продвинутого управления — использовать внешние инструменты, например Aerich:

bash
pip install aerich

Инициализация (в FastAPI или вручную)

python
from tortoise.contrib.fastapi import register_tortoise register_tortoise( app, db_url="sqlite://db.sqlite3", modules={"models": ["app.models"]}, generate_schemas=True, add_exception_handlers=True, )

Поддержка типов полей

Поле Описание
IntField Целое число.
CharField(max_length) Строка.
BooleanField() Логическое значение.
DateField() / DatetimeField() Дата и время.
JSONField() Хранение JSON.
ForeignKeyField() Связь многие-к-одному.
ManyToManyField() Связь многие-ко-многим.

Когда использовать Tortoise ORM

  • Когда ты пишешь асинхронное приложение (FastAPI, Starlette, Quart).

  • Когда хочешь Django-подобный стиль без всего Django.

  • Для простых или средних по размеру проектов с акцентом на скорость.