Wie man mehr als 1000 holt?

Wie kann ich mehr als 1000 Rekord aus dem Datenspeicher holen und alles in einer einzigen Liste an Django weitergeben?

16 Solutions collect form web for “Wie man mehr als 1000 holt?”

Ab Version 1.3.6 (freigegeben am 17.08.2010) können Sie

Aus dem Changelog:

Ergebnisse von Datenspeicheranzahl () Abfragen und Offsets für alle Datenspeicherabfragen werden bei 1000 nicht mehr begrenzt .

Nur für die Rekord-Fetch-Grenze von 1000 Einträgen ist jetzt weg:

http://googleappengine.blogspot.com/2010/02/app-engine-sdk-131-including-major.html

Zitat:

Nicht mehr 1000 Ergebnisgrenze – das ist richtig: Mit Hinzufügung von Cursors und dem Höhepunkt vieler kleinerer Datastore-Stabilität und Leistungsverbesserungen in den letzten Monaten sind wir jetzt zuversichtlich genug, um die maximale Ergebnisgrenze insgesamt zu beseitigen. Ob Sie einen Abruf machen, iterieren oder einen Cursor verwenden, es gibt keine Grenzen für die Anzahl der Ergebnisse.

App-Engine gibt Ihnen eine schöne Art und Weise "Paging" durch die Ergebnisse von 1000 durch die Bestellung auf Keys und mit dem letzten Schlüssel als der nächste Offset. Sie liefern sogar einen Beispielcode hier:

http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Queries_on_Keys

Obwohl ihr Beispiel die Abfragen über viele Anfragen ausbreitet, können Sie die Seitengröße von 20 auf 1000 ändern und in einer Schleife abfragen und die Quarysets kombinieren. Darüber hinaus können Sie itertools verwenden, um die Abfragen zu verknüpfen, ohne sie zu bewerten, bevor sie benötigt werden.

Zum Beispiel, um zu zählen, wie viele Zeilen über 1000:

class MyModel(db.Expando): @classmethod def count_all(cls): """ Count *all* of the rows (without maxing out at 1000) """ count = 0 query = cls.all().order('__key__') while count % 1000 == 0: current_count = query.count() if current_count == 0: break count += current_count if current_count == 1000: last_key = query.fetch(1, 999)[0].key() query = query.filter('__key__ > ', last_key) return count 

Jedes Mal, wenn dies als Begrenzung auftaucht, frage ich mich immer noch, warum brauchst du mehr als 1.000 Ergebnisse? " Wussten Sie, dass Google selbst nicht mehr als 1.000 Ergebnisse ausmacht? Versuchen Sie diese Suche: http://www.google.ca/search?hl=de&client=firefox-a&rls=org.mozilla:en-US:official&hs=qhu&q=1000+results&start=1000&sa=N Ich wusste das nicht bis Vor kurzem, weil ich nie die Zeit genommen hatte, in die 100. Seite der Suchergebnisse auf einer Abfrage zu klicken.

Wenn Sie tatsächlich mehr als 1.000 Ergebnisse zurück an den Benutzer zurückgeben, dann denke ich, es gibt ein größeres Problem an der Hand als die Tatsache, dass der Datenspeicher wird nicht zulassen, dass Sie es tun.

Ein möglicher (legitimer) Grund, dass viele Ergebnisse nötig sind, wenn Sie eine große Operation auf den Daten machten und eine Zusammenfassung darstellen (z. B. was ist der Durchschnitt aller dieser Daten). Die Lösung für dieses Problem (das im Google I / O-Vortrag gesprochen wird) besteht darin, die zusammenfassenden Daten on-the-fly zu berechnen und zu speichern.

Sie können nicht.

Ein Teil der FAQ gibt an, dass es keine Möglichkeit gibt, über die Zeile 1000 einer Abfrage zuzugreifen, die Erhöhung des "OFFSET" wird nur zu einer kürzeren Ergebnismenge führen,

Dh: OFFSET 999 -> 1 Ergebnis kommt zurück.

Aus Wikipedia:

App Engine beschränkt die maximalen Zeilen, die von einer Entität zurückgegeben werden, um 1000 Zeilen pro Datastore-Aufruf zu erhalten. Die meisten Web-Datenbank-Anwendungen verwenden Paging und Caching, und daher nicht verlangen, dass viele Daten auf einmal, so ist dies ein Nicht-Problem in den meisten Szenarien. Wenn eine Anwendung benötigt mehr als 1.000 Datensätze pro Betrieb, kann es seine Eigene Client-Side-Software oder eine Ajax-Seite, um eine Operation auf einer unbegrenzten Anzahl von Zeilen durchzuführen.

Von http://code.google.com/appengine/docs/whatisgoogleappengine.html

Ein weiteres Beispiel für eine Servicegrenze ist die Anzahl der von einer Abfrage zurückgegebenen Ergebnisse. Eine Abfrage kann maximal 1000 Ergebnisse zurückgeben. Abfragen, die mehr Ergebnisse zurückgeben würden, geben nur das Maximum zurück. In diesem Fall ist eine Anforderung, die eine solche Abfrage ausführt, nicht wahrscheinlich, eine Anforderung vor dem Timeout zurückzugeben, aber die Grenze ist vorhanden, um Ressourcen auf dem Datenspeicher zu sparen.

Von http://code.google.com/appengine/docs/datastore/gqlreference.html

Hinweis: Eine LIMIT-Klausel hat maximal 1000. Wenn ein Grenzwert größer als das Maximum angegeben ist, wird das Maximum verwendet. Das gleiche Maximum gilt für die Methode holen () der GqlQuery-Klasse.

Hinweis: Wie der Offset-Parameter für die Prozedur fetch () reduziert ein OFFSET in einem GQL-Abfrage-String nicht die Anzahl der aus dem Datenspeicher geholten Entitäten. Es wirkt sich nur auf die Ergebnisse aus, die durch die Methode holen () zurückgegeben werden. Eine Abfrage mit einem Offset hat Leistungsmerkmale, die linear mit der Offsetgröße übereinstimmen.

Von http://code.google.com/appengine/docs/datastore/queryclass.html

Die Begrenzungs- und Offset-Argumente steuern, wie viele Ergebnisse aus dem Datenspeicher geholt werden und wie viele von der Methode fetch () zurückgegeben werden:

  • Der Datenspeicher holt Offset + Limit Ergebnisse an die Anwendung. Die ersten Offset-Ergebnisse werden nicht vom Datenspeicher selbst übersprungen.

  • Die Methode holen () holt die ersten Offset-Ergebnisse aus und gibt dann den Rest zurück (Limit-Ergebnisse).

  • Die Abfrage hat Leistungsmerkmale, die linear mit dem Offsetbetrag plus dem Limit übereinstimmen.

Was das bedeutet ist

Wenn Sie eine singuläre Abfrage haben, gibt es keine Möglichkeit, etwas außerhalb des Bereichs 0-1000 anzufordern.

Der zunehmende Offset wird nur die 0 erhöhen

 LIMIT 1000 OFFSET 0 

Wird 1000 Zeilen zurückgeben,

und

 LIMIT 1000 OFFSET 1000 

Wird 0 Zeilen zurückgeben , so dass es unmöglich ist, mit einer einzigen Abfrage-Syntax, fetch 2000 Ergebnisse entweder manuell oder mit der API.

Die einzige plausible Ausnahme

Ist ein numerischer Index auf dem Tisch zu erstellen, dh:

  SELECT * FROM Foo WHERE ID > 0 AND ID < 1000 SELECT * FROM Foo WHERE ID >= 1000 AND ID < 2000 

Wenn Ihre Daten oder Abfrage nicht diese "ID" Hardcoded Identifier haben können, dann sind Sie aus Glück

Dieses 1K-Limit-Problem ist behoben.

 query = MyModel.all() for doc in query: print doc.title 

Durch das Behandeln des Abfrageobjekts als iterable: Der Iterator ruft Ergebnisse aus dem Datenspeicher in kleinen Batches ab, so dass die App die Iteration auf Ergebnisse stoppen kann, um zu vermeiden, dass mehr geholt wird, als es benötigt wird. Iteration stoppt, wenn alle Ergebnisse, die mit der Abfrage übereinstimmen, abgerufen wurden. Wie bei fetch (), die Iterator-Schnittstelle nicht Cache-Ergebnisse, so dass die Schaffung eines neuen Iterator aus dem Query-Objekt wird die Abfrage erneut ausführen.

Die maximale Chargengröße beträgt 1K. Und du hast doch noch die Auto-Datastore-Quoten.

Aber mit dem Plan 1.3.1 SDK haben sie Cursor eingeführt, die serialisiert und gespeichert werden können, damit ein zukünftiger Aufruf die Abfrage beginnen kann, wo sie zuletzt aufgehört hat.

Die 1000 Datensatzgrenze ist eine harte Grenze in Google AppEngine.

Diese Präsentation http://sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine erklärt, wie man effizient mit Hilfe von AppEngine Daten durchsucht.

(Grundsätzlich mit einer numerischen ID als Schlüssel und Angabe einer WHERE-Klausel auf der ID.)

Abrufen, obwohl die Remote-API noch Probleme hat, wenn mehr als 1000 Datensätze. Wir schrieben diese kleine Funktion, um über einen Tisch in Stücke zu iterieren:

 def _iterate_table(table, chunk_size = 200): offset = 0 while True: results = table.all().order('__key__').fetch(chunk_size+1, offset = offset) if not results: break for result in results[:chunk_size]: yield result if len(results) < chunk_size+1: break offset += chunk_size 

Wir verwenden etwas in unserer ModelBase Klasse, die ist:

 @classmethod def get_all(cls): q = cls.all() holder = q.fetch(1000) result = holder while len(holder) == 1000: holder = q.with_cursor(q.cursor()).fetch(1000) result += holder return result 

Das bekommt bei jedem Modell die 1000 Abfragegrenze, ohne darüber nachzudenken. Ich nehme an, eine Schlüsselversion wäre genauso einfach zu implementieren.

 class Count(object): def getCount(self,cls): class Count(object): def getCount(self,cls): """ Count *all* of the rows (without maxing out at 1000) """ count = 0 query = cls.all().order('__key__') while 1: current_count = query.count() count += current_count if current_count == 0: break last_key = query.fetch(1, current_count-1)[0].key() query = query.filter('__key__ > ', last_key) return count 
 entities = [] for entity in Entity.all(): entities.append(entity) 

So einfach ist das. Beachten Sie, dass es einen RPC für jede Entität gibt, die viel langsamer ist als das Abrufen in Chunks. Also, wenn Sie über die Leistung besorgt sind, gehen Sie wie folgt vor:

Wenn du weniger als 1M Items hast:

 entities = Entity.all().fetch(999999) 

Andernfalls einen Cursor verwenden.

Es ist auch zu beachten:

 Entity.all().fetch(Entity.all().count()) 

Liefert 1000 max und sollte nicht verwendet werden.

JJG: Ihre Lösung oben ist fantastisch, außer dass es eine Endlosschleife verursacht, wenn Sie 0 Datensätze haben. (Ich habe das herausgefunden, während ich einige meiner Berichte vor Ort teste).

Ich habe den Anfang der while-Schleife geändert, um so auszusehen:

 while count % 1000 == 0: current_count = query.count() if current_count == 0: break 

Um den Inhalt der beiden Abfragen zusammenzufügen:

 list1 = first query list2 = second query list1 += list2 

Liste 1 enthält jetzt alle 2000 Ergebnisse.

Die vorgeschlagene Lösung funktioniert nur, wenn Einträge nach Schlüssel sortiert werden … Wenn Sie zuerst nach einer anderen Spalte sortieren, müssen Sie immer noch eine Limit- (Offset-, Zähl-) Klausel verwenden, dann gilt die 1000-Eintragungsbegrenzung weiterhin. Es ist dasselbe, wenn man zwei Anfragen verwendet: eine für das Abrufen von Indizes (mit Bedingungen und Sortierung) und eine andere Verwendung wo Index in () mit einer Untermenge von Indizes aus dem ersten Ergebnis, da die erste Anforderung nicht mehr als 1000 Schlüssel zurückgeben kann? (Der Abschnitt "Google Queries on Keys " lautet nicht eindeutig, wenn wir nach Schlüssel sortieren müssen, um die 1000 Ergebnisbegrenzung zu entfernen)

Dies ist in der Nähe der Lösung von Gabriel, aber nicht holen die Ergebnisse, die es nur zählt sie:

 count = 0 q = YourEntityClass.all().filter('myval = ', 2) countBatch = q.count() while countBatch > 0: count += countBatch countBatch = q.with_cursor(q.cursor()).count() logging.info('Count=%d' % count) 

Funktioniert perfekt für meine Fragen und schnell auch (1,1 Sekunden, um 67.000 Entitäten zu zählen)

Beachten Sie, dass die Abfrage kein Ungleichheitsfilter oder ein Satz sein darf oder der Cursor nicht funktioniert und Sie diese Ausnahme erhalten:

AssertionError: Kein Cursor für eine MultiQuery verfügbar (Abfragen mit "IN" oder "! =" Operatoren)

Wenn Sie NDB verwenden:

 @staticmethod def _iterate_table(table, chunk_size=200): offset = 0 while True: results = table.query().order(table.key).fetch(chunk_size + 1, offset=offset) if not results: break for result in results[:chunk_size]: yield result if len(results) < chunk_size + 1: break offset += chunk_size 
  • Modell Design-Muster für Google App-Engine
  • NDB: Abfrageergebnisse sortieren
  • Zuweisen eines Autors zu einer Entität während der Erstellung
  • Erstellen Sie eine gut aussehende URL für einen Schlüssel mit Vorfahren
  • Image Upload in Google App Engine
  • Leseverzögerung im App Engine-Datenspeicher nach put ()
  • Wie bekomme ich den Wert eines meiner Modelle in Google App Engine
  • Google App Engine Versioning im Datenspeicher
  • Google App Engine (DataStore) Referenzierte Entity Deletion
  • Appengine Rückreferenzen - brauchen Composite-Index?
  • Wie kommst du nicht automatisch eine db.ReferenceProperty in Google App Engine?
  • Python ist die beste Programmiersprache der Welt.