fix: cards fetch optimization

This commit is contained in:
2025-04-15 10:59:41 +04:00
parent c08c2c04c4
commit 68f94cc9a4
3 changed files with 86 additions and 15 deletions

View File

@@ -1,14 +1,16 @@
from collections import defaultdict
import lexorank
import math
from fastapi import HTTPException
from sqlalchemy import select, func, update, delete, insert, and_
from sqlalchemy import select, func, update, delete, insert, and_, Select
from sqlalchemy.orm import joinedload, selectinload
from starlette import status
from card_attributes import CardAttributesCommandHandler
from card_attributes.exceptions import CardAttributeException
from models import *
from schemas.base import PaginationSchema
from schemas.card import *
from schemas.client import ClientDetailsSchema
from services import card_group
@@ -179,7 +181,61 @@ class CardsService(BaseService):
.subquery()
)
async def get_summary(self, full: bool = False) -> CardSummaryResponse:
@staticmethod
def _apply_pagination(query: Select, pagination: PaginationSchema) -> Select:
offset = (pagination.page - 1) * pagination.items_per_page
query = (
query
.offset(offset)
.limit(pagination.items_per_page)
)
return query
@staticmethod
def _apply_summary_filters(query: Select, request: GetCardSummariesRequest) -> Select:
if not request.full:
return query.where(Card.is_completed == False)
if request.card_id:
query = query.where(Card.id == request.card_id)
if request.card_name:
query = query.where(Card.name.like(f"%{request.card_name}%"))
if request.status_id:
query = query.where(Card.current_status_id == request.status_id)
elif request.board_id:
query = query.where(Card.board_id == request.board_id)
elif request.project_id:
query = (
query
.join(Board)
.where(Board.project_id == request.project_id)
)
if request.client_id:
query = query.where(Card.client_id == request.client_id)
if request.marketplace_key:
query = query.where(Card.base_marketplace_key == request.marketplace_key)
if request.shipping_warehouse_id:
query = query.where(Card.shipping_warehouse_id == request.shipping_warehouse_id)
query = query.order_by(Card.created_at.desc())
return query
async def _summaries_pagination_info(self, query: Select, pagination: PaginationSchema) -> PaginationInfoSchema:
if not pagination.items_per_page:
return PaginationInfoSchema(total_pages=0, total_items=0)
summaries = (await self.session.scalars(query)).all()
total_items = len(summaries)
return PaginationInfoSchema(
total_pages=math.ceil(total_items / pagination.items_per_page),
total_items=total_items,
)
async def get_summary(self, request: GetCardSummariesRequest, pagination: PaginationSchema) -> CardSummaryResponse:
price_subquery = self._get_price_subquery()
products_quantity_subquery = self._get_products_quantity_subquery()
q = (
@@ -210,13 +266,14 @@ class CardsService(BaseService):
Card.is_deleted == False,
)
)
if not full:
q = q.where(
Card.is_completed == False,
# Card.current_status != CardStatus.COMPLETED
)
else:
q = q.order_by(Card.created_at.desc())
q = self._apply_summary_filters(q, request)
pagination_info = await self._summaries_pagination_info(q, pagination)
if pagination.page and pagination.items_per_page:
q = CardsService._apply_pagination(q, pagination)
cards_query = await self.session.execute(q)
summaries = []
for card, total_price, rank, products_count in cards_query.all():
@@ -247,7 +304,7 @@ class CardsService(BaseService):
attributes=attributes,
)
)
return CardSummaryResponse(summaries=summaries)
return CardSummaryResponse(summaries=summaries, pagination_info=pagination_info)
async def get_all(self) -> CardGetAllResponse:
cards_stmt = (