5.6 Написание запросов к БД используя SQLAlchemy, часть 1
6 из 6 шагов пройдено
1 из 1 баллa  получен

Метод получения всех категорий

Чтобы вывести все категории, в файле routers/category.py, мы первым делом должны подключить зависимость сессии БД, и выполнить запрос.

from sqlalchemy import select


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

В запросе мы выбираем таблицу Category и делаем выборку по полю is_active, чтобы получить только активные категории. Подробнее о методе select вы можете посмотреть в документации.

В старых версиях SQLAlchemy запрос выглядит следующим образом.

categories = db.query(Category).filter(Category.is_active == True).all()

Запустим сервер, и проверим работу: 

Мы получаем все категории, но на данном этапе она у нас одна.

 

Метод удаления категории

На данном этапе мы создадим нашу конечную точку, которая будет "удалять" категорию. Но на самом деле, мы будем менять у нее значение поля is_active, чтобы она не отображалась в списке категорий.

from sqlalchemy import update


@router.delete('/delete')
async def delete_category(db: Annotated[Session, Depends(get_db)], category_id: int):
    category = 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'
        )
    db.execute(update(Category).where(Category.id == category_id).values(is_active=False))
    db.commit()
    return {
        'status_code': status.HTTP_200_OK,
        'transaction': 'Category delete is successful'
    }

Разберем код подробнее. Первым делом мы получаем данные нашей категории из БД, это сделано для того, чтобы в случае отсутствия категории с введенным в запросе category_id, вызвать ошибку 404 с текстом "There is no category found".

Далее мы выполняем запрос об изменении значения поля is_active на False, в таблице Category записи с id равным введенному в запросе category_id.  И возвращаем код ответа 200, с текстом об успешном удалении категории.

Если мы хотим удалять категории, то запрос будет выглядеть следующим образом.

delete(Category).where(Category.id == category_id)

Подробнее о методах update и delete вы можете посмотреть в документации.

Запустим сервер и проверим работу. Попробуем "удалить" категорию с id=1.

Отправив запрос, мы получаем код ответа 200, и текст об успешном удалении категории. Теперь если мы откроем в редакторе нашу базу данных, мы увидим что значение поля is_active было изменено:

И в заключении этого шага, попробуем удалить категорию с id, которого у нас не существует.

В результате мы получаем код ошибки 404, и текст что категория не была найдена. В следующем шаге мы реализуем возможность изменять наши категории.


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

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

@Anonymous_38661511, Просто в дальнейшем права на создание и удаление категорий будут только у администратора. И мне кажется не совсем правильно будет удалять категорию и все товары внутри. Единственное что можно, это добавить проверку, что если категория существует, то можно менять значение поля статуса на активное.

Изменен Илья Перминов

if category is None:

    raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail='There is no category found' )

Является ли ошибкой заменить if category is None: на if not category:

@Алексей_Бойко, я считаю что лучше не надо. Все таки мы проверяем на пустое значение, а не на правду или ложь. Но у меня местами есть тоже через not)

Изменен Илья Перминов