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 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.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
@@ -142,31 +142,20 @@ async def get_stocks_data(
|
|||||||
.subquery()
|
.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 = (
|
is_master_subquery = (
|
||||||
select(
|
select(
|
||||||
Product.id.label('product_id'),
|
Product.id.label("product_id"),
|
||||||
func.coalesce(is_master_first_subquery.c.is_master, False).label('is_master')
|
# 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,
|
||||||
)
|
)
|
||||||
.select_from(
|
|
||||||
Product
|
|
||||||
)
|
)
|
||||||
.outerjoin(
|
).label("is_master"),
|
||||||
is_master_first_subquery,
|
|
||||||
Product.id == is_master_first_subquery.c.master_product_id
|
|
||||||
)
|
)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
@@ -264,7 +253,7 @@ async def get_stocks_data(
|
|||||||
.label('warehouse_stock'),
|
.label('warehouse_stock'),
|
||||||
mix_stock_full_subquery.c.mix_stock.label('mix_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'),
|
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'),
|
func.coalesce(slaves_stock_subquery.c.slaves_stock, 0).label('slaves_stock'),
|
||||||
MarketplaceProduct.price_recommended.label('price_recommended'),
|
MarketplaceProduct.price_recommended.label('price_recommended'),
|
||||||
MarketplaceProduct.is_archived.label('is_archived'),
|
MarketplaceProduct.is_archived.label('is_archived'),
|
||||||
@@ -317,7 +306,6 @@ async def get_stocks_data(
|
|||||||
)
|
)
|
||||||
|
|
||||||
result = await session.execute(stmt)
|
result = await session.execute(stmt)
|
||||||
|
|
||||||
marketplace_products = result.all()
|
marketplace_products = result.all()
|
||||||
response: List[StockData] = []
|
response: List[StockData] = []
|
||||||
for (marketplace_product,
|
for (marketplace_product,
|
||||||
|
|||||||
Reference in New Issue
Block a user