fix: cards fetch optimization
This commit is contained in:
@@ -5,7 +5,7 @@ from typing import Annotated
|
|||||||
from fastapi import APIRouter, Depends, Response, UploadFile
|
from fastapi import APIRouter, Depends, Response, UploadFile
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from backend.dependecies import SessionDependency, CurrentUserDependency
|
from backend.dependecies import SessionDependency, CurrentUserDependency, PaginationDependency
|
||||||
from backend.session import get_session
|
from backend.session import get_session
|
||||||
from generators.deal_pdf_generator.generator import DealTechSpecPdfGenerator
|
from generators.deal_pdf_generator.generator import DealTechSpecPdfGenerator
|
||||||
from models import User
|
from models import User
|
||||||
@@ -78,7 +78,7 @@ async def change_status(
|
|||||||
return await CardsService(session).change_status_manual(request, user)
|
return await CardsService(session).change_status_manual(request, user)
|
||||||
|
|
||||||
|
|
||||||
@card_router.get(
|
@card_router.post(
|
||||||
'/summaries',
|
'/summaries',
|
||||||
response_model=CardSummaryResponse,
|
response_model=CardSummaryResponse,
|
||||||
operation_id='getCardSummaries',
|
operation_id='getCardSummaries',
|
||||||
@@ -86,9 +86,10 @@ async def change_status(
|
|||||||
)
|
)
|
||||||
async def get_summary(
|
async def get_summary(
|
||||||
session: Annotated[AsyncSession, Depends(get_session)],
|
session: Annotated[AsyncSession, Depends(get_session)],
|
||||||
full: Optional[bool]
|
request: GetCardSummariesRequest,
|
||||||
|
pagination: PaginationDependency,
|
||||||
):
|
):
|
||||||
return await CardsService(session).get_summary(full)
|
return await CardsService(session).get_summary(request, pagination)
|
||||||
|
|
||||||
|
|
||||||
@card_router.post(
|
@card_router.post(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import List, Optional, Union
|
|||||||
from pydantic import constr
|
from pydantic import constr
|
||||||
|
|
||||||
from schemas.attribute import CardAttributeSchema
|
from schemas.attribute import CardAttributeSchema
|
||||||
from schemas.base import BaseSchema, OkMessageSchema
|
from schemas.base import BaseSchema, OkMessageSchema, PaginationInfoSchema
|
||||||
from schemas.billing import CardBillRequestSchema
|
from schemas.billing import CardBillRequestSchema
|
||||||
from schemas.board import BoardSchema
|
from schemas.board import BoardSchema
|
||||||
from schemas.card_tag import CardTagSchema
|
from schemas.card_tag import CardTagSchema
|
||||||
@@ -164,6 +164,18 @@ class CardChangeStatusRequest(BaseSchema):
|
|||||||
new_status: int
|
new_status: int
|
||||||
|
|
||||||
|
|
||||||
|
class GetCardSummariesRequest(BaseSchema):
|
||||||
|
full: bool
|
||||||
|
card_id: Optional[int | str] = None
|
||||||
|
card_name: Optional[str] = None
|
||||||
|
marketplace_key: Optional[str] = None
|
||||||
|
shipping_warehouse_id: Optional[int] = None
|
||||||
|
client_id: Optional[int] = None
|
||||||
|
project_id: Optional[int] = None
|
||||||
|
board_id: Optional[int] = None
|
||||||
|
status_id: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
class CardCreateRequest(BaseSchema):
|
class CardCreateRequest(BaseSchema):
|
||||||
name: str
|
name: str
|
||||||
status_id: int
|
status_id: int
|
||||||
@@ -345,6 +357,7 @@ class CardQuickCreateResponse(BaseSchema):
|
|||||||
|
|
||||||
class CardSummaryResponse(BaseSchema):
|
class CardSummaryResponse(BaseSchema):
|
||||||
summaries: List[CardSummary]
|
summaries: List[CardSummary]
|
||||||
|
pagination_info: PaginationInfoSchema
|
||||||
|
|
||||||
|
|
||||||
class CardAddServicesResponse(BaseSchema):
|
class CardAddServicesResponse(BaseSchema):
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
import lexorank
|
import lexorank
|
||||||
|
import math
|
||||||
from fastapi import HTTPException
|
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 sqlalchemy.orm import joinedload, selectinload
|
||||||
from starlette import status
|
from starlette import status
|
||||||
|
|
||||||
from card_attributes import CardAttributesCommandHandler
|
from card_attributes import CardAttributesCommandHandler
|
||||||
from card_attributes.exceptions import CardAttributeException
|
from card_attributes.exceptions import CardAttributeException
|
||||||
from models import *
|
from models import *
|
||||||
|
from schemas.base import PaginationSchema
|
||||||
from schemas.card import *
|
from schemas.card import *
|
||||||
from schemas.client import ClientDetailsSchema
|
from schemas.client import ClientDetailsSchema
|
||||||
from services import card_group
|
from services import card_group
|
||||||
@@ -179,7 +181,61 @@ class CardsService(BaseService):
|
|||||||
.subquery()
|
.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()
|
price_subquery = self._get_price_subquery()
|
||||||
products_quantity_subquery = self._get_products_quantity_subquery()
|
products_quantity_subquery = self._get_products_quantity_subquery()
|
||||||
q = (
|
q = (
|
||||||
@@ -210,13 +266,14 @@ class CardsService(BaseService):
|
|||||||
Card.is_deleted == False,
|
Card.is_deleted == False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if not full:
|
|
||||||
q = q.where(
|
q = self._apply_summary_filters(q, request)
|
||||||
Card.is_completed == False,
|
|
||||||
# Card.current_status != CardStatus.COMPLETED
|
pagination_info = await self._summaries_pagination_info(q, pagination)
|
||||||
)
|
|
||||||
else:
|
if pagination.page and pagination.items_per_page:
|
||||||
q = q.order_by(Card.created_at.desc())
|
q = CardsService._apply_pagination(q, pagination)
|
||||||
|
|
||||||
cards_query = await self.session.execute(q)
|
cards_query = await self.session.execute(q)
|
||||||
summaries = []
|
summaries = []
|
||||||
for card, total_price, rank, products_count in cards_query.all():
|
for card, total_price, rank, products_count in cards_query.all():
|
||||||
@@ -247,7 +304,7 @@ class CardsService(BaseService):
|
|||||||
attributes=attributes,
|
attributes=attributes,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return CardSummaryResponse(summaries=summaries)
|
return CardSummaryResponse(summaries=summaries, pagination_info=pagination_info)
|
||||||
|
|
||||||
async def get_all(self) -> CardGetAllResponse:
|
async def get_all(self) -> CardGetAllResponse:
|
||||||
cards_stmt = (
|
cards_stmt = (
|
||||||
|
|||||||
Reference in New Issue
Block a user