refactor: optimize is_master subquery using EXISTS instead of COUNT
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from typing import Union, TypedDict
|
||||
|
||||
from sqlalchemy import select, func, and_, cast, String, case, or_
|
||||
from sqlalchemy import select, func, and_, cast, String, case, or_, exists
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
@@ -142,31 +142,20 @@ async def get_stocks_data(
|
||||
.subquery()
|
||||
)
|
||||
|
||||
is_master_first_subquery = (
|
||||
select(
|
||||
ProductRelation.master_product_id,
|
||||
(func.count(ProductRelation.master_product_id) > 0).label('is_master')
|
||||
)
|
||||
.where(
|
||||
ProductRelation.relation_type == ProductRelationType.MAIN_PRODUCT
|
||||
)
|
||||
.group_by(
|
||||
ProductRelation.master_product_id
|
||||
)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
is_master_subquery = (
|
||||
select(
|
||||
Product.id.label('product_id'),
|
||||
func.coalesce(is_master_first_subquery.c.is_master, False).label('is_master')
|
||||
)
|
||||
.select_from(
|
||||
Product
|
||||
)
|
||||
.outerjoin(
|
||||
is_master_first_subquery,
|
||||
Product.id == is_master_first_subquery.c.master_product_id
|
||||
Product.id.label("product_id"),
|
||||
# EXISTS возвращает bool, не нужно COUNT > 0 и GROUP BY
|
||||
exists(
|
||||
select(1)
|
||||
.select_from(ProductRelation)
|
||||
.where(
|
||||
and_(
|
||||
ProductRelation.master_product_id == Product.id,
|
||||
ProductRelation.relation_type == ProductRelationType.MAIN_PRODUCT,
|
||||
)
|
||||
)
|
||||
).label("is_master"),
|
||||
)
|
||||
.subquery()
|
||||
)
|
||||
@@ -264,7 +253,7 @@ async def get_stocks_data(
|
||||
.label('warehouse_stock'),
|
||||
mix_stock_full_subquery.c.mix_stock.label('mix_stock'),
|
||||
func.coalesce(in_block_subquery.c.in_block_value, 1).label('in_block_value'),
|
||||
is_master_subquery.c.is_master.label('is_master'),
|
||||
func.coalesce(is_master_subquery.c.is_master, False).label('is_master'),
|
||||
func.coalesce(slaves_stock_subquery.c.slaves_stock, 0).label('slaves_stock'),
|
||||
MarketplaceProduct.price_recommended.label('price_recommended'),
|
||||
MarketplaceProduct.is_archived.label('is_archived'),
|
||||
@@ -317,7 +306,6 @@ async def get_stocks_data(
|
||||
)
|
||||
|
||||
result = await session.execute(stmt)
|
||||
|
||||
marketplace_products = result.all()
|
||||
response: List[StockData] = []
|
||||
for (marketplace_product,
|
||||
|
||||
Reference in New Issue
Block a user