2015-09-10 7 views
5

Ich bin mir bewusst, dass reguläre Abfrage oder die Iterator-Methode queryset ausgewertet und den gesamten Datensatz in einem Schuss zurückgibt.Abrufen von Abfrage-Set-Daten eins nach dem anderen

zum Beispiel, nehmen Sie dies:

my_objects = MyObject.objects.all() 
for rows in my_objects:   # Way 1 
for rows in my_objects.iterator(): # Way 2 

Frage

Bei beiden Verfahren werden alle Zeilen abgerufen werden, in einem single-go.Is es eine Möglichkeit, in Djago, dass die queryset Reihen sein können nacheinander aus der Datenbank abgerufen.

Warum diese seltsame Anforderung

Derzeit meine Abfrage lässt holt sagt Zeilen n, aber ich bekommen irgendwann Python and Django OperationalError (2006, 'MySQL server has gone away').

so eine Abhilfe für dieses zu haben, ich zur Zeit eine seltsame while Looping logic.So frage mich, bin mit, wenn es irgendeine nativen oder eingebaute Methode oder ist meine Frage auch logisch in erster Linie ist !! :)

Antwort

2

Ich denke, Sie suchen nach limit your query set.

Zitat von oben Link:

eine Untergruppe von Array-Slicing-Syntax von Python Verwenden Sie Ihre QuerySet auf eine bestimmte Anzahl von Ergebnissen zu begrenzen. Dies entspricht den SQL-Klauseln LIMIT und OFFSET.

Mit anderen Worten: Wenn Sie mit einer Zählung beginnen Sie dann Schleife über und Scheiben nehmen, wie Sie sie benötigen ..

cnt = MyObject.objects.count() 
start_point = 0 
inc = 5 
while start_point + inc < cnt: 
    filtered = MyObject.objects.all()[start_point:inc] 
    start_point += inc 

Natürlich müssen Sie möglicherweise diese mehr Fehler behandeln ..

+0

Ich gehe davon aus Sie in ausgesehen haben hier die aktuelle Ausgabe Festsetzung, die natürlich bevorzugt werden :) würde – Sayse

+0

das ist definitiv eine Weise, die ich in Betracht gezogen haben, während sie um zu graben, sieht neat.I bin frage mich, ob es noch einen anderen * nativen * Weg im Django gibt ohne Grenzen? Was das eigentliche Problem betrifft, so ist es mit der Django-Version verwandt, aber da das ganze Projekt darauf basiert, kann ich nichts dagegen tun ..... – NoobEditor

+0

@NoobEditor - Ich denke, das ist ungefähr so ​​nativ wie es geht, da dies die von Ihnen durchgeführte Abfrage ändert. Sie werden weiterhin mehrere Abfragen in der Datenbank ausführen, aber nur N Ergebnisse auf einmal zurückgeben. Die andere Option besteht darin, zu prüfen, was Sie tatsächlich zurückgeben müssen, und "Werte" zu verwenden, um nur diese Felder zurückzugeben. (Auch wenn ich in meinem Beispiel nur 5 auf einmal holen würde, würde ich mir vorstellen, dass Sie viel mehr als das auf einmal bewältigen können) – Sayse

2

Das Abrufen von Zeile für Zeile ist möglicherweise schlimmer. Vielleicht möchten Sie in Batches für 1000s usw. abrufen. Ich habe used this django snippet (nicht meine Arbeit) erfolgreich mit sehr großen Abfragegruppen. Es braucht keine Speicher und keine Probleme mit weggehenden Verbindungen.

Hier ist der Ausschnitt aus diesem Link:

import gc 

def queryset_iterator(queryset, chunksize=1000): 
    ''''' 
    Iterate over a Django Queryset ordered by the primary key 

    This method loads a maximum of chunksize (default: 1000) rows in it's 
    memory at the same time while django normally would load all rows in it's 
    memory. Using the iterator() method only causes it to not preload all the 
    classes. 

    Note that the implementation of the iterator does not support ordered query sets. 
    ''' 
    pk = 0 
    last_pk = queryset.order_by('-pk')[0].pk 
    queryset = queryset.order_by('pk') 
    while pk < last_pk: 
     for row in queryset.filter(pk__gt=pk)[:chunksize]: 
      pk = row.pk 
      yield row 
     gc.collect() 
+0

Ihre URL öffnet nicht Mate! – NoobEditor

+0

@ e4c5: Umgeleitet zu http: //https//djangosnippets.org/snippets/1949/ .. aber es zeigt keine Seite..check noch einmal fella !! : D – NoobEditor

+0

Antwort aktualisiert durch Kopieren und Einfügen des Snippets. – e4c5

1

zu lösen (2006, 'MySQL Server gegangen ist weg') Problem, Ihr Ansatz nicht logisch ist. Wenn Sie für jeden Eintrag auf die Datenbank zugreifen, erhöht sich die Anzahl der Abfragen, was in Zukunft zu Problemen führen wird, wenn die Nutzung Ihrer Anwendung zunimmt. Ich denke, Sie sollten mysql Verbindung nach der Iteration aller Elemente des Ergebnisses zu schließen, und wenn Sie dann versuchen, eine andere Abfrage zu machen, wird Django eine neue Verbindung erstellen.

from django.db import connection: 
connection.close() 

Refer this for more details

+0

Problem ist, dass "Verbindung" wird beim Abrufen der Abfrage abgesetzt werden ... daher der Fehler.So auch wenn ich schließe und starten und neue Verbindung, ich wieder das gleiche Problem.Ich habe versucht 'connections.connection' &' ist_verwendbar' aber Keine Hilfe! : \ – NoobEditor