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:
Scarriffle
2026-07-29 12:23:12 +02:00
parent 4034b97cf3
commit 4728a839ea
3 changed files with 119 additions and 6 deletions

View File

@@ -9,7 +9,7 @@ import json
import pytest
from app.crud import product_tracking
from app.crud import product_to_out, product_tracking, products_to_out_bulk
from app.models import (
BaseUnit,
Category,
@@ -92,6 +92,28 @@ def test_einzelstueck_ohne_kategorie_ist_object(db):
assert product_tracking(db, product) == "object"
# ---- Gebündelte Listen-Ausgabe ----
def test_bulk_liste_zaehlt_bestand_wie_einzeln(db):
# products_to_out_bulk muss denselben Bestand liefern wie product_to_out
# Lot-Summe für Mengen, Item-Anzahl für Einzelstücke.
reis = Product(name="Reis", base_unit=BaseUnit.gram, package_size=500)
db.add(reis)
db.flush()
a = _loc(db, "Regal")
object_add(db, reis, 1000, a.id, None) # 1000 g als Charge
powerbank = _individual_product(db, name="Powerbank")
for _ in range(2):
db.add(Item(uid=generate_uid(db), product_id=powerbank.id))
db.commit()
einzeln = {product_to_out(db, p).id: product_to_out(db, p).stock for p in [reis, powerbank]}
gebuendelt = {o.id: o.stock for o in products_to_out_bulk(db, [reis, powerbank])}
assert gebuendelt == einzeln
assert gebuendelt[reis.id] == 1000
assert gebuendelt[powerbank.id] == 2
def test_neue_oberkategorie_ist_gegenstand(db):
out = create_category(CategoryCreate(name="Werkzeug"), db, None)
assert out.tracking == CategoryTracking.object