python / expert
Snippet
Batch-Verarbeitungs-QuerySet-Generator für große Array-Felder
Keyset-Paginierung über Primärschlüssel-Auswertung vermeidet die exponentielle Abfrageverlangsamung der herkömmlichen OFFSET/LIMIT-Paginierung bei riesigen Django-QuerySets. Mithilfe von Python-Generatoren werden große Datenmengen in kontrollierten Chunk-Arrays im Arbeitsspeicher verarbeitet.
snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
from typing import Generator, Anyfrom django.db.models import QuerySetdef chunk_queryset(qs: QuerySet, chunk_size: int = 500) -> Generator[list[Any], None, None]:pk = 0base_qs = qs.order_by('pk')while True:chunk = list(base_qs.filter(pk__gt=pk)[:chunk_size])if not chunk:breakpk = chunk[-1].pkyield chunk
django
Erklärung
1
from typing import Generator, Any
Importiert Typ-Hinweise für Generatorfunktionen und Modellinstanzen.
2
from django.db.models import QuerySet
Importiert die Django QuerySet-Typdefinition für Datenbank-Operationen.
3
def chunk_queryset(qs: QuerySet, chunk_size: int = 500) -> Generator[list[Any], None, None]:
Definiert eine Generatorfunktion, die QuerySets speicherschonend in Batches unterteilt.
4
pk = 0
Initialisiert den Primärschlüssel-Zeiger für die Keyset-Paginierung.
5
base_qs = qs.order_by('pk')
Stellt eine deterministische Sortierung nach dem Primärschlüssel sicher.
6
while True:
Startet eine Schleife, die beendet wird, wenn alle Ergebnisse verarbeitet wurden.
7
chunk = list(base_qs.filter(pk__gt=pk)[:chunk_size])
Lädt einen Ausschnitt von Modellen mit einem Primärschlüssel größer als der letzte Zeiger.
8
if not chunk:
Prüft, ob die Abfrage eine leere Liste zurückgegeben hat.
9
break
Beendet die Schleife, wenn keine Datensätze mehr vorhanden sind.
10
pk = chunk[-1].pk
Aktualisiert den Zeiger auf den Primärschlüssel des letzten Elements im aktuellen Batch.
11
yield chunk
Gibt den aktuellen Daten-Batch per yield an den Aufrufer zurück.