[PYTHON] Als ich die von Django generierte Abfrage überprüfte, wurde sie in großer Anzahl ausgegeben

Django:1.10

Wenn Sie eine Abfrage mit Django generieren, wird eine große Anzahl von Abfragen ausgegeben, wenn Sie diese nicht sorgfältig schreiben.

Abfrageprotokollausgabe

Schreiben Sie zunächst die Protokolleinstellungen in manage.py, um die Abfrage an die Serverkonsole auszugeben.

manage.py


LOGGING = {
    'version': 1,
    'formatters': {
        'all': {
            'format': '%(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'all',
        },
    },
    'loggers': {
        'django': {
           'handlers': ['console'],
           'level': 'DEBUG',
        },
    },
}

Überprüfen Sie die Abfrage

Lassen Sie uns eine Abfrage ausführen, um die Liste der Bücher zu erhalten, die vom ausgewählten Autor veröffentlicht wurden, der zuletzt verwendet wurde.

So generieren Sie eine Abfrage mit dem IN-Operator in Django http://qiita.com/nakkun/items/86a94e65fe6785325f54

Quelle


books = Book.objects.filter(author_id__in = form.cleaned_data['author'])

Ausführungsergebnis


(0.002) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" IN (1, 3); args=(1, 3)

Die SQL lief wie erwartet. Ich habe die gleiche Abfrage mit "author_ \ _ id_ \ in" wie unten gezeigt. (Die Anzahl von "" ist unterschiedlich)

Quelle


books = Book.objects.filter(author__id__in = form.cleaned_data['author'])

Im Fall von "author_ \ _ id_ \ _in" habe ich mich gefragt, ob sie beitreten würden, aber das war nicht der Fall.

Eine große Anzahl von Fragen! ??

Bisher gibt es kein besonderes Problem. Wenn Sie jedoch versuchen, den Autorennamen danach anzuzeigen, lautet das Ausführungsergebnis wie folgt.

Quelle


books = Book.objects.filter(author_id__in = form.cleaned_data['author'])
[print(book.author.name) for book in books]

Ausführungsergebnis


(0.003) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" IN (1, 3); args=(1, 3)
(0.001) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" = 1; args=(1,)
Hirotsugu Mori
(0.000) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" = 3; args=(3,)
Miyagiya Masamitsu
(0.000) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" = 3; args=(3,)
Miyagiya Masamitsu
(0.001) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" = 3; args=(3,)
Miyagiya Masamitsu
(0.000) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" = 3; args=(3,)
Miyagiya Masamitsu

Ich habe eine ziemlich nutzlose Anfrage gestellt.

Sie müssen also eine Quelle schreiben, die eine verknüpfte Abfrage wie folgt ausgibt:

Quelle


books = Book.objects.select_related().filter(author_id__in = form.cleaned_data['author'])
[print(book.author.name) for book in books]

Ausführungsergebnis


(0.004) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id", "books_author"."id", "books_author"."name" FROM "books_book" INNER JOIN "books_author" ON ("books_book"."author_id" = "books_author"."id") WHERE "books_book"."author_id" IN (1, 3); args=(1, 3)
Hirotsugu Mori
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu

Jetzt müssen Sie die SQL nur noch einmal ausgeben.

Es ist möglicherweise besser, während der Überprüfung des SQL zu entwickeln, bevor Sie sich daran gewöhnen, damit Sie keine große Menge an SQL werfen, ohne es zu wissen.

Ergänzung

Über 3 andere Methoden.

① Verwendung von prefetch_related

Quelle


books = Book.objects.filter(author_id__in = form.cleaned_data['author']).prefetch_related('author')
[print(book.author.name) for book in books]

Ausführungsergebnis


(0.001) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" IN (1, 3); args=(1, 3)
(0.001) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" IN (1, 3); args=(1, 3)
Hirotsugu Mori
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu

② Ausgehend vom Autorenmodell

Quelle


authors = Author.objects.filter(id__in = form.cleaned_data['author'])
[[print(book.atuhor.name) for book in author.book_set.all()] for author in authors]

Ausführungsergebnis


(0.002) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" IN (1, 3); args=(1, 3)
(0.001) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" = 1; args=(1,)
Hirotsugu Mori
(0.000) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" = 3; args=(3,)
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu

③ Verwenden Sie prefetch_related ab dem Autorenmodell

Quelle


authors = Author.objects.filter(id__in = form.cleaned_data['author']).prefetch_related("book_set")
[[print(book.atuhor.name) for book in author.book_set.all()] for author in authors]

Ausführungsergebnis


(0.002) SELECT "books_author"."id", "books_author"."name" FROM "books_author" WHERE "books_author"."id" IN (1, 3); args=(1, 3)
(0.002) SELECT "books_book"."id", "books_book"."name", "books_book"."author_id" FROM "books_book" WHERE "books_book"."author_id" IN (1, 3); args=(1, 3)
Hirotsugu Mori
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu
Miyagiya Masamitsu

Recommended Posts

Als ich die von Django generierte Abfrage überprüfte, wurde sie in großer Anzahl ausgegeben
django geodjango Ich habe mich darauf bezogen, als ich im Tutorial feststeckte (Bearbeitung)
Was ich getan habe, als ich wütend war, es mit der Option enable-shared einzufügen
Ich dachte, ich hätte die pyc-Datei kürzlich nicht gesehen, aber sie wurde von python3 in pycache isoliert
Wo befindet sich der ausgelöste Speicherort im Exception-Stack-Trace? Wo wurde es erzeugt?
Holen Sie sich die Abfragezeichenfolge (Abfragezeichenfolge) mit Django
Als ich versuchte, Python auszuführen, wurde ich zum Microsoft Store übersprungen
Django ~ Lass es uns im Browser anzeigen ~
Als ich in IPython versuchte, den Wert zu sehen, war es ein Generator, also kam ich auf ihn, als ich frustriert war.
[Python] Vorsichtsmaßnahmen beim Erfassen von Daten durch Scraping und Einfügen in die Liste
Als ich untersuchte, ob die COTOHA-API Mansai verstehen konnte, war dies vernünftig.
Die Funktion _authenticate_with_backend wurde in django auth.autenticate nicht mehr unterstützt
Wenn ich matplotlib in Python versuche, heißt es'cairo.Context '.
Ich habe die Sitzungsaufbewahrungsdauer von Django überprüft
Ich habe den im Qiita Adventskalender 2016 gelöschten Kalender überprüft
Ich habe die Referenzgeschwindigkeit überprüft, wenn ich Python-Liste, Wörterbuch und Set-Typ verwendet habe.
Es wurde TLE, als ich den Vorgang mit der Druckfunktion im Competition Pro bestätigte
Der von pysheng gespeicherte Dateiname war eine Hexadezimalzahl, daher habe ich ihn behoben.
Ich habe versucht, das Telefon klingeln zu lassen, als es auf dem IoT-Post veröffentlicht wurde
Wenn ich das Webapi crawle, das beim Rendern angezeigt wird, wurde es mit CORS abgespielt
Python: Kann in Lambda wiederholt werden
Was ich durch die Teilnahme am ISUCON10-Qualifying gelernt habe
Als ich den AtCoder Beginner Contest ausprobierte, war es ein schreckliches Ergebnis, also schaue ich zurück
Eine Geschichte, nach der ich süchtig war, als ich in Go nil als Funktionsargument angab