5.9 Добавление асинхронности в запросах SQLAlchemy
4 из 4 шагов пройдено

Работа с зависимостью сессий

Следующим шагом нам нужно изменить файл backend/db_depends.py, чтобы мы могли работать с асинхронными запросами.

from sqlalchemy.ext.asyncio import AsyncSession
from app.backend.db import async_session_maker


async def get_db() -> AsyncSession:
    async with async_session_maker() as session:
        yield session

На этом подготовка к асинхронным запросам завершена, далее мы начнем дорабатывать наши запросы, чтобы они могли выполняться асинхронно. 

 

Работа с запросами

Начнем с конечной точки, выводящей все категории, для этого в файле routers/category.py изменим ее:

from sqlalchemy.ext.asyncio import AsyncSession


@router.get('/all_categories')
async def get_all_categories(db: Annotated[AsyncSession, Depends(get_db)]):
    categories = await db.scalars(select(Category).where(Category.is_active == True))
    return categories.all()

При использовании асинхронного подключения метод scalars становится корутиной и для получения объекта результата ScalarResult необходимо дождаться её выполнения с помощью выражения await, только после этого, мы можем задействовать метод all() у полученного объекта ScalarResult

По аналогии изменим функцию создания категорий:

@router.post('/create')
async def create_category(db: Annotated[AsyncSession, Depends(get_db)], create_category: CreateCategory):
    await db.execute(insert(Category).values(name=create_category.name,
                                       parent_id=create_category.parent_id,
                                       slug=slugify(create_category.name)))
    await db.commit()
    return {
        'status_code': status.HTTP_201_CREATED,
        'transaction': 'Successful'
    }

В данном случе мы добавляем выражение await для самого запроса и метода commit, для подтверждения изменений.

И также перепишем код, для остальных конечных точек:

@router.put('/update_category')
async def update_category(db: Annotated[AsyncSession, Depends(get_db)], category_id: int, update_category: CreateCategory):
    category = await db.scalar(select(Category).where(Category.id == category_id))
    if category is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='There is no category found'
        )

    await db.execute(update(Category).where(Category.id == category_id).values(
            name=update_category.name,
            slug=slugify(update_category.name),
            parent_id=update_category.parent_id))


    await db.commit()
    return {
        'status_code': status.HTTP_200_OK,
        'transaction': 'Category update is successful'
    }


@router.delete('/delete')
async def delete_category(db: Annotated[AsyncSession, Depends(get_db)], category_id: int):
    category = await db.scalar(select(Category).where(Category.id == category_id))
    if category is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='There is no category found'
        )
    await db.execute(update(Category).where(Category.id == category_id).values(is_active=False))
    await db.commit()
    return {
        'status_code': status.HTTP_200_OK,
        'transaction': 'Category delete is successful'
    }

Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Нет обсуждений. Начните первое.