Класс AsyncAttrs
Класс AsyncAttrs добавляет в модели SQLAlchemy
поддержку асинхронного доступа к атрибутам, которые
загружаются лениво. Обычно такой доступ через
await невозможен, потому что ленивая загрузка
выполняется синхронно и блокирует event loop. Класс
AsyncAttrs предоставляет атрибут awaitable_attrs,
через который можно дождаться загрузки нужного поля.
Параметров у класса нет, его достаточно указать среди
базовых классов модели.
Синтаксис
class Base(AsyncAttrs, DeclarativeBase):
pass
Пример
Давайте создадим базовый класс с поддержкой асинхронных атрибутов и модель статьи:
from sqlalchemy import String, Text
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, AsyncAttrs
class Base(AsyncAttrs, DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
text: Mapped[str] = mapped_column(Text)
Пример
Давайте асинхронно получим значение отложенного
атрибута через awaitable_attrs:
<+python+>
import asyncio
from sqlalchemy import String, Text, select
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, AsyncAttrs
class Base(AsyncAttrs, DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
text: Mapped[str] = mapped_column(Text)
async def main():
engine = create_async_engine('sqlite:///:memory:')
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async_session = async_sessionmaker(engine, expire_on_commit=False)
async with async_session() as session:
session.add(Article(title='article', text='some text'))
await session.commit()
async with async_session() as session:
res = await session.execute(select(Article))
article = res.scalar_one()
title = await article.awaitable_attrs.title
print(title)
await engine.dispose()
asyncio.run(main())
<-python+>
Результат выполнения кода:
"article"
Пример
Давайте асинхронно загрузим сразу несколько отложенных атрибутов одной модели:
<+python+>
import asyncio
from sqlalchemy import String, Text, select
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, AsyncAttrs
class Base(AsyncAttrs, DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
text: Mapped[str] = mapped_column(Text)
async def main():
engine = create_async_engine('sqlite:///:memory:')
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async_session = async_sessionmaker(engine, expire_on_commit=False)
async with async_session() as session:
session.add(Article(title='article', text='some text'))
await session.commit()
async with async_session() as session:
res = await session.execute(select(Article))
article = res.scalar_one()
title = await article.awaitable_attrs.title
text = await article.awaitable_attrs.text
print(title, text)
await engine.dispose()
asyncio.run(main())
<-python+>
Результат выполнения кода:
"article some text"
Смотрите также
-
функцию
create_async_engine,
которая создает асинхронный движок базы данных -
класс
async_scoped_session,
который управляет асинхронными сессиями в рамках задачи -
класс
AsyncAttrs,
который предоставляет асинхронный доступ к атрибутам моделей -
раздел
async,
который описывает работу SQLAlchemy с asyncio