56 lines
1.6 KiB
Python
56 lines
1.6 KiB
Python
from typing import Optional
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import aliased
|
|
|
|
from db.models import Category
|
|
|
|
|
|
class CategoriesRepository:
|
|
async def get_category_by_id(
|
|
self, session: AsyncSession, category_id: int
|
|
) -> Optional[Category]:
|
|
stmt = select(Category).where(Category.id == category_id)
|
|
return await session.scalar(stmt)
|
|
|
|
async def get_categories_by_parent_id(
|
|
self, session: AsyncSession, parent_id: Optional[int] = None
|
|
) -> list[Category]:
|
|
stmt = select(Category).where(Category.parent_id == parent_id)
|
|
result = await session.scalars(stmt)
|
|
|
|
return list(result)
|
|
|
|
async def get_category_path(self, session: AsyncSession, category_id: int):
|
|
base = select(Category.id, Category.parent_id, Category.name).where(
|
|
Category.id == category_id
|
|
)
|
|
|
|
cte = base.cte(name="path", recursive=True)
|
|
|
|
parent = aliased(Category)
|
|
|
|
cte = cte.union_all(
|
|
select(parent.id, parent.parent_id, parent.name).join(
|
|
cte, cte.c.parent_id == parent.id
|
|
)
|
|
)
|
|
|
|
stmt = select(cte)
|
|
|
|
result = await session.execute(stmt)
|
|
|
|
rows = result.all()
|
|
|
|
return list(reversed(rows))
|
|
|
|
async def add_category(
|
|
self, session: AsyncSession, *, name: str, parent_id: Optional[int]
|
|
) -> Category:
|
|
category = Category(name=name, parent_id=parent_id)
|
|
|
|
session.add(category)
|
|
await session.commit()
|
|
|
|
return category
|