2010-09-26 6 views
5

He leído en varias ubicaciones que GAE elevó el límite de 1000 registros en consultas y recuentos, sin embargo, parece que puedo obtener un recuento de los registros hasta 1000. No sacaré más de 1000 consultas a la vez, pero los requisitos son tales que necesito un recuento de los registros coincidentes.Google App Engine: obtener el recuento de los registros que coinciden con los criterios de más de 1000

Entiendo que puede utilizar los cursores para "paginar" a través del conjunto de datos, pero recorrer solo para obtener un conteo parece demasiado. Es de suponer que cuando dijeron que "levantaron" el límite, era el límite estricto: todavía necesita pasar por los resultados 1000 a la vez, ¿estoy en lo correcto?

¿Debo utilizar otro método que no sea el método .all()/filter para generar más de 1000 cuentas?

Gracias de antemano por toda su ayuda!

Respuesta

7

El comportamiento de Query.count() es inconsistente con la documentación cuando no se especifica explícitamente ningún límite; la documentación indica que contará "hasta que termine el conteo o se agote el tiempo de espera". GAE Issue 3671 informó este error (hace aproximadamente 3 semanas).

La solución provisional: especifique explícitamente un límite y luego se usará ese valor (en lugar del valor predeterminado de 1,000).

Prueba de http://shell.appspot.com demuestra esto:

# insert 1500 TestModel entites ... 
# ... 
>>> TestModel.all(keys_only=True).count() 
1000L 
>>> TestModel.all(keys_only=True).count(10000) 
1500L 

También veo el mismo comportamiento en la última versión del servidor de desarrollo (1.3.7) mediante esta sencilla aplicación de prueba:

from google.appengine.ext import webapp, db 
from google.appengine.ext.webapp.util import run_wsgi_app 

class Blah(db.Model): pass 

class MainPage(webapp.RequestHandler): 
    def get(self): 
     for i in xrange(3): 
      db.put([Blah() for i in xrange(500)]) # can only put 500 at a time ... 
     c = Blah.all().count() 
     c10k = Blah.all().count(10000) 
     self.response.out.write('%d %d' % (c,c10k)) 
     # prints "1000 1500" on its first run 

application = webapp.WSGIApplication([('/', MainPage)]) 

def main(): run_wsgi_app(application) 
if __name__ == '__main__': main() 
+0

Voy a intentar tu solución y ver qué tan lejos consigo. La idea de que debe proporcionar un límite al conteo es evidentemente absurda, pero ojalá se resuelva pronto. ¡Gracias por su amabilidad! – etc

+1

No es absurdo: el recuento cuesta O (n) tiempo, y presumiblemente hay un límite superior sobre cuánto tiempo está dispuesto a gastar en contar. –

+0

¡Eso es raro !? (p.s. Su segundo ejemplo no puede funcionar ya que el lote puesto está limitado a 500) – systempuntoout

-1

acuerdo a este App Engine blog post, el límite de 1000 entidades acaba de ser eliminado para count (y offset) en la versión 1.3.6. El límite ya se había eliminado para fetch a partir de la versión 1.3.1. Actualice a la última versión y el límite debe ser eliminado.

No necesita pasar por los resultados de 1000 a la vez (aunque podría, e incluso podría ser más eficiente); pasar simplemente en el número máximo de resultados que le gustaría volver:

for m in MyModel.all().fetch(82000): 
     # ... 

En versiones anteriores a 1.3.1, el número aprobada en tenía que ser menor o igual a 1000.

+0

La mejor solución sería actualizarse a la última versión. Desafortunadamente, hay un error en la última versión que hace que la documentación no sea coherente con el comportamiento. Count() devolverá solo 1,000 resultados a menos que proporcione explícitamente un límite superior a 1,000. –

+0

Como el Sr. Underhill declaró, por cualquier razón, error o no, una cuenta simple en una consulta solo produce 1000 incluso con la última versión. – etc

1

Como se ha sugerido en Issue 3671, puede establecer el límite en Ninguno (en lugar de un número superior a 1000, que aún es útil para limitar el recuento) si desea contar todos los registros, aunque no se recomienda hacer esto y en cambio desnormalizar los recuentos en una transacción .

total_records = query.count(limit=None) 
Cuestiones relacionadas