Backend: Produktliste gebuendelt laden (N+1 weg, deutlich schneller)
list_products rief product_to_out je Artikel auf - pro Artikel mehrere Abfragen (Bestand, abgelaufene Chargen, Codes, Bild, Lazy-Relationen). Bei vielen Artikeln = hunderte Queries und mehrere Sekunden. Neu: products_to_out_bulk holt Bestand/Abgelaufen/Codes/Bild je einmal fuer alle und laedt Relationen eager (joinedload/selectinload). Ergebnis identisch (Test), aber nur noch wenige Queries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
|
||||
from fastapi.responses import Response
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm import Session, joinedload, selectinload
|
||||
|
||||
from ..crud import product_to_out, product_tracking
|
||||
from ..crud import product_to_out, product_tracking, products_to_out_bulk
|
||||
from ..database import get_db
|
||||
from ..deps import get_current_user, require_admin
|
||||
from ..models import (
|
||||
@@ -56,7 +56,15 @@ def list_products(
|
||||
Kategorie zählen die Unterkategorien mit: Wer auf "Süßwaren" filtert, will
|
||||
auch "Schokolade" sehen.
|
||||
"""
|
||||
query = db.query(Product)
|
||||
query = db.query(Product).options(
|
||||
# Relationen vorab laden, damit products_to_out_bulk kein N+1 auslöst.
|
||||
joinedload(Product.category),
|
||||
joinedload(Product.shop),
|
||||
joinedload(Product.display_unit),
|
||||
joinedload(Product.min_stock_unit),
|
||||
selectinload(Product.field_values),
|
||||
selectinload(Product.location_min_stocks).joinedload(ProductLocationMinStock.location),
|
||||
)
|
||||
if q:
|
||||
like = f"%{q}%"
|
||||
query = query.filter(Product.name.ilike(like))
|
||||
@@ -65,7 +73,7 @@ def list_products(
|
||||
elif category_id is not None:
|
||||
query = query.filter(Product.category_id.in_(descendant_ids(db, category_id)))
|
||||
products = query.order_by(Product.name).all()
|
||||
return [product_to_out(db, p) for p in products]
|
||||
return products_to_out_bulk(db, products)
|
||||
|
||||
|
||||
@router.get("/lookup", response_model=LookupResult)
|
||||
|
||||
Reference in New Issue
Block a user