[PYTHON] Verwenden Sie prefetch_related bequem mit Django

Die Anzahl der Django-Projekte im Unternehmen nimmt zu, und die Anzahl der uncoolen Abfragen wird wahrscheinlich zunehmen. Hinterlassen Sie daher einfach eine Notiz.

Verwenden Sie prefetch_related, da es katastrophal wäre, die Abfrage jedes Mal zu überspringen, wenn Sie eine Schleife ausführen, wenn Sie die umgekehrte Referenz des Fremdschlüssels abrufen oder das Referenzziel von Many-to-Many abrufen, ohne über die Verwendung von ORM nachzudenken. Die Geschichte des Schmelzens

Wenn es sich um einen normalen Fremdschlüssel handelt, können Sie ihn mit select_related durch die erforderliche Hierarchie ziehen.

Normalerweise verwenden

Ein solches Modell vorerst

from django.db import models

class Campaign(models.Model):
    name = models.CharField(max_length=255)
    created_at = models.DateTimeField()

class Creative(models.Model):
    name = models.CharField(max_length=255, default="")
    campaign = models.ForeignKey(Campaign)
    created_at = models.DateTimeField()

Wenn Sie Campaign von Creative subtrahieren möchten, können Sie select_related verwenden, um Campaign beizutreten und abzurufen, ohne es bei jeder Schleife auszuwählen.

for creative in Creative.objects.all().select_related():
	print(creative.campaign)

Verwenden Sie prefetch_related, um die Liste der Motive aus der Kampagne abzurufen

for campaign in Campaign.objects.all().prefetch_related("creative_set"):
	print(campaign.creative_set.all())

Es scheint, dass alle Kampagnen einmal gezogen werden, anstatt beizutreten, und die Liste der Kampagne.id wird dort eingezogen, wo sie sich befindet. Nun, es ist besser als jedes Mal zu fliegen, und in den meisten Fällen scheint es kein Problem zu sein.

Das Eingrenzen der Kampagne mit Creative erfolgt übrigens normalerweise mit einer Abfrage

Campaign.object.filter(creative_set__name="aaa")

Prefetch-Objekt verwenden

Wenn Sie einfach prefetch_related verwenden, können Sie nur das Ding von XXXX_set.all () erhalten. Wenn Sie das creative_set eingrenzen, wird die Abfrage bei jeder Schleife ausgeführt, was Sie sehr traurig macht.

for campaign in Campaign.objects.all().prefetch_related("creative_set"):
	print(campaign.creative_set.filter(name__startswith="hoge"))

Wenn Sie das Ziel der umgekehrten Referenz oder von Many-to-Many mithilfe eines Filters eingrenzen oder die Reihenfolge angeben möchten, verwenden Sie das Prefetch-Objekt aus 1.7 von Django. Dank dieses Typen habe ich das Gefühl, dass sich Djangos ORM stark verbessert hat.

from django.db import models
from django.db.models import Prefetch

for campaign in Campaign.objects.all().prefetch_related(Prefetch("creative_set", queryset=Creative.objects.filter(name__startswith="hoge").order_by("-created_at"), to_attr="creatives")):
	if len(campaign.creatives) > 0:
        print(campaign.id, creatives[0].id)

Unabhängig davon, wie viele Kampagnen Sie haben, müssen Sie die Abfrage nur zweimal überspringen.

Abfrage anzeigen

Wenn Sie eine Abfrage optimieren, werden Sie wahrscheinlich die Django-Shell verwenden, um die Abfrage zu überprüfen. Es ist daher eine gute Idee, sich mit dem Logger herumzuschlagen, damit die SQL-Anweisung angezeigt wird, wenn Sie die Abfrage mit der Shell treffen. Ich denke, dass ich mit den Protokolleinstellungen herumspiele, wenn ich es normal mache, aber ich bin froh, wenn ich die Protokollstufe von django.db.backends nur bei der Untersuchung von Abfragen auf DEBUG setze.

settings.py


LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        },
    }
}

Für die Optimierung nach Ansicht ist es einfach, die Abfrage mithilfe der django-debug-Symbolleiste zu überprüfen.

Recommended Posts

Verwenden Sie prefetch_related bequem mit Django
Verwenden Sie Gentelella mit Django
Verwenden Sie WENIGER mit Django
Verwenden Sie MySQL mit Django
[Django] Verwenden Sie MessagePack mit dem Django REST-Framework
Verwenden Sie Unicode 6.0-Piktogramme mit Django / MySQL
Internationalisierung mit Django
CRUD mit Django
Verwenden Sie den Docker-Entwicklungscontainer bequem mit VS Code
Verwenden Sie Python / Django mit dem Windows Azure Cloud Service!
Authentifizieren Sie Google mit Django
Django 1.11 wurde mit Python3.6 gestartet
Laden Sie Dateien mit Django hoch
Verwenden Sie mecab-ipadic-neologd mit igo-python
Entwicklungsverdauung mit Django
Verwenden Sie ansible mit cygwin
Verwenden Sie pipdeptree mit virtualenv
PDF mit Django ausgeben
[Python] Verwenden Sie JSON mit Python
Verwenden Sie Mock mit Pytest
Markdown-Ausgabe mit Django
Verwenden Sie den Indikator mit pd.merge
Verwenden Sie Mecab mit Python 3
Verwenden Sie Tensorboard mit Chainer
Verwenden Sie DynamoDB mit Python
Verwenden Sie pip mit MSYS2
Erste Schritte mit Django 1
Mail mit Django senden
Verwenden Sie Python 3.8 mit Anaconda
Verwenden Sie Copyright mit Spacemacs
Datei-Upload mit Django
Verwenden Sie Python mit Docker
Verwenden Sie TypeScript mit Django-Kompressor
Pooling mechanisieren mit Django
Verwenden Sie Enum mit SQLAlchemy
Verwenden Sie Tensorboard mit NNabla
Verwenden Sie GPS mit Edison
Django ab heute
Erste Schritte mit Django 2
Verwenden Sie nim mit Jupyter
Mach Django mit CodeStar (Python3.6.8, Django2.2.9)
Verwenden Sie die Trello-API mit Python
Verwenden Sie gemeinsam genutzten Speicher mit gemeinsam genutzten Bibliotheken
Verwenden Sie benutzerdefinierte Tags mit PyYAML
Verwenden Sie Richtungsdiagramme mit networkx
Fangen Sie mit Django an! ~ Tutorial ⑤ ~
Verwenden Sie TensorFlow mit Intellij IDEA
Es war zu einfach, eine vorhandene Datenbank mit Django zu verwenden
Minimale Konfigurations-Website-Umgebung mit Django
Erstellen Sie eine API mit Django
Verwenden Sie die Twitter-API mit Python
Verwenden Sie pip mit Jupyter Notebook
Mach Django mit CodeStar (Python3.8, Django2.1.15)
Stellen Sie Django serverlos mit Lambda bereit
Python3 + Django ~ Mac ~ mit Apache
Verwenden Sie DATE_FORMAT mit dem SQLAlchemy-Filter
Verwenden Sie TUN / TAP mit Python
Erste Schritte mit Python Django (1)
Erstellen Sie eine Homepage mit Django
Erste Schritte mit Python Django (4)
Erstellen Sie eine Webanwendung mit Django