diff --git a/fastfood/cruds/menu.py b/fastfood/cruds/menu.py index 604a40e..0d3c479 100644 --- a/fastfood/cruds/menu.py +++ b/fastfood/cruds/menu.py @@ -35,7 +35,7 @@ class MenuCrud: select( m, func.count(distinct(s.id)).label("submenus_count"), - func.count(distinct(d.id)).label("dishes_count") + func.count(distinct(d.id)).label("dishes_count"), ) .join(s, s.parent_menu == m.id, isouter=True) .join(d, d.parent_submenu == s.id, isouter=True) @@ -46,7 +46,7 @@ class MenuCrud: menu = menu.scalars().one_or_none() if menu is None: return None - return menu + return menu @staticmethod async def update_menu_item( diff --git a/fastfood/cruds/submenu.py b/fastfood/cruds/submenu.py index b4edde0..c8ebe47 100644 --- a/fastfood/cruds/submenu.py +++ b/fastfood/cruds/submenu.py @@ -1,7 +1,8 @@ from uuid import UUID -from sqlalchemy import delete, func, select, update +from sqlalchemy import delete, distinct, func, select, update from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.orm import aliased from fastfood import models, schemas @@ -12,7 +13,7 @@ class SubMenuCrud: async with session: query = select(models.SubMenu).where(models.SubMenu.parent_menu == menu_id) submenus = await session.execute(query) - return submenus.scalars().all() + return submenus @staticmethod async def create_submenu_item( @@ -35,21 +36,19 @@ class SubMenuCrud: session: AsyncSession, ): async with session: - query = select(models.SubMenu).where(models.SubMenu.id == submenu_id) + s = aliased(models.SubMenu) + d = aliased(models.Dish) + query = ( + select(s, func.count(distinct(d.id))) + .join(d, s.id == d.parent_submenu, isouter=True) + .group_by(s.id) + .where(s.id == submenu_id) + ) submenu = await session.execute(query) submenu = submenu.scalars().one_or_none() if submenu is None: return None - - dish_query = ( - select(func.count(models.Dish.id)) - .join(models.SubMenu) - .filter(models.Dish.parent_submenu == models.SubMenu.id) - ) - dishes = await session.execute(dish_query) - submenu.dishes_count = dishes.scalars().one_or_none() - - return submenu + return submenu @staticmethod async def update_submenu_item( @@ -67,7 +66,7 @@ class SubMenuCrud: await session.commit() qr = select(models.SubMenu).where(models.SubMenu.id == submenu_id) updated_submenu = await session.execute(qr) - return updated_submenu.scalars().one() + return updated_submenu @staticmethod async def delete_submenu_item(submenu_id: UUID, session: AsyncSession): diff --git a/fastfood/models.py b/fastfood/models.py index d404646..98d2d10 100644 --- a/fastfood/models.py +++ b/fastfood/models.py @@ -26,9 +26,9 @@ class Base(DeclarativeBase): def __eq__(self, other): classes_match = isinstance(other, self.__class__) a, b = deepcopy(self.__dict__), deepcopy(other.__dict__) - a.pop('_sa_instance_state', None) - b.pop('_sa_instance_state', None) - attrs_match = (a == b) + a.pop("_sa_instance_state", None) + b.pop("_sa_instance_state", None) + attrs_match = a == b return classes_match and attrs_match def __ne__(self, other): diff --git a/fastfood/routers/menu.py b/fastfood/routers/menu.py index 9bbb0ab..0b9b324 100644 --- a/fastfood/routers/menu.py +++ b/fastfood/routers/menu.py @@ -38,6 +38,7 @@ async def get_menu( session: AsyncSession = Depends(get_async_session), ): result = await crud.get_menu_item(menu_id=menu_id, session=session) + if not result: raise HTTPException(status_code=404, detail="menu not found") return result diff --git a/fastfood/routers/submenu.py b/fastfood/routers/submenu.py index 80fb205..b322532 100644 --- a/fastfood/routers/submenu.py +++ b/fastfood/routers/submenu.py @@ -18,7 +18,7 @@ async def get_submenus( menu_id: UUID, session: AsyncSession = Depends(get_async_session) ): result = await crud.get_submenus(menu_id=menu_id, session=session) - return result + return result.scalars().all() @router.post("/", status_code=201) @@ -66,7 +66,7 @@ async def update_submenu( submenu=submenu, session=session, ) - return result + return result.scalars().one() @router.delete("/{submenu_id}") diff --git a/tests/test_crud.py b/tests/test_crud.py index faf8a45..9b97117 100644 --- a/tests/test_crud.py +++ b/tests/test_crud.py @@ -1,13 +1,13 @@ from uuid import UUID -from sqlalchemy.ext.asyncio import AsyncSession -from fastfood.cruds.submenu import SubMenuCrud -from fastfood.models import Menu, SubMenu, Dish -from fastfood.cruds.menu import MenuCrud -from fastfood.schemas import Menu as menuschema -from fastfood.schemas import SubMenuRead as submenuschema -from fastfood.schemas import MenuBase as menubaseschema import pytest +from sqlalchemy.ext.asyncio import AsyncSession + +from fastfood.cruds.menu import MenuCrud +from fastfood.cruds.submenu import SubMenuCrud +from fastfood.models import Dish, Menu, SubMenu +from fastfood.schemas import Menu as menuschema +from fastfood.schemas import MenuBase as menubaseschema @pytest.mark.asyncio @@ -24,7 +24,7 @@ async def test_menu(asession: AsyncSession) -> None: assert menu == req_menu req_menus = await MenuCrud.get_menus(asession) - # assert menu == req_menus.first() + assert menu == req_menus.scalars().one() menu.title = "updatedMenu" await MenuCrud.update_menu_item( @@ -48,8 +48,12 @@ async def test_submenu(asession: AsyncSession) -> None: await asession.refresh(menu) menu_id: UUID = menu.id submenu: SubMenu = SubMenu( - title="submenu", description="", parent_menu=menu_id, + title="submenu", + description="", + parent_menu=menu_id, ) submenu = await SubMenuCrud.create_submenu_item( - menu_id, menubaseschema.model_validate(submenu), asession, + menu_id, + menubaseschema.model_validate(submenu), + asession, )