44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
from typing import TypeVar, Generic, List
|
|
import strawberry
|
|
from sqlalchemy import func, Select
|
|
from database.transaction import get_session
|
|
|
|
Item = TypeVar("Item")
|
|
|
|
|
|
@strawberry.type
|
|
class PaginationWindow(Generic[Item]):
|
|
items: List[Item] = strawberry.field(
|
|
description="The list of items in this pagination window."
|
|
)
|
|
|
|
total_items_count: int = strawberry.field(
|
|
description="Total number of items in the filtered dataset."
|
|
)
|
|
|
|
|
|
async def get_pagination_window(
|
|
query: Select,
|
|
item_type: type,
|
|
limit: int,
|
|
offset: int = 0,
|
|
) -> PaginationWindow:
|
|
if limit <= 0:
|
|
raise Exception(f"limit ({limit}) must be > 0")
|
|
|
|
async with get_session() as db:
|
|
cnt_query = query.with_only_columns(func.count())
|
|
total_items_count = (await db.scalars(cnt_query)).one()
|
|
|
|
# if offset != 0 and not 0 <= offset < total_items_count:
|
|
# raise Exception(f"offset ({offset}) is out of range " f"(0-{total_items_count - 1})")
|
|
|
|
async with get_session() as db:
|
|
data = (await db.scalars(query.limit(limit).offset(offset))).all()
|
|
dataset = [item_type(**i.as_dict()) for i in data]
|
|
|
|
return PaginationWindow(
|
|
items=dataset,
|
|
total_items_count=total_items_count
|
|
)
|