2010-07-12 6 views
5

¿Cuál es la mejor manera de determinar cuántos modelos de cierto tipo hay en el almacén de datos de mi aplicación? La documentación dice que MyKind.all().count() es solo marginalmente mejor que recuperar todos los datos, y tiene un límite de 1000. Esto no es útil, porque espero tener más de 6000 instancias de MyKind almacenadas.GAE: ¿La mejor manera de determinar cuántos de una clase se almacena?

¿Hay una mejor manera de hacerlo? ¿Qué pasa si solo obtengo las llaves y las cuento?

Estoy usando Python.

+0

Duplicado de la pregunta existente: http://stackoverflow.com/questions/2988864/how-to-get-the-number-of-rows-in-a-table-in-a-datastore/2989513 –

Respuesta

1

Mantenga un objeto contador para su aplicación almacenado en la base de datos y actualícelo siempre que cree y elimine objetos.

+0

Eso es tipo de un dolor No está SECO, y ahora tengo que buscar todo el código para encontrar el momento en que se cree o elimine 'MyKind'. –

+2

@Rosarch Si las instancias de 'MyKind' son' put() 'en todo su código, tal vez su diseño se beneficiaría de una aplicación más consistente de DRY. :-) –

3

Si lo hace solo claves que debe ser bastante rápido, ya que esto sólo tiene que leer el índice y doesn en realidad, captar cualquier entidad. Utilice un cursor y el bucle hasta que el recuento() devuelve menos de 1000.

2

This SO question tiene una respuesta (por @jgeewax) que es casi derecha (condición equivocada salida, como os comentaba allí). Aquí es un fijo ...:

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 True: 
      current_count = query.count() 
      if current_count == 0: return count 
      count += current_count 

      if current_count == 1000: 
       last_key = query.fetch(1, 999)[0].key() 
       query = query.filter('__key__ > ', last_key) 

     return count 

El problema de rendimiento, por supuesto, es que para ello se utiliza una consulta real al almacén de datos por cada 1.000 artículos que ha - desnormalización cosas manteniendo un recuento real, como sugiere @Chris, va a utilizar ahora menos consultas. (¡Asegúrese de utilizar un sharded counter u otras formas de efficient counters como explica App Engine Fan!).

La desnormalización es una realidad con DB no relacionales, y, hecho correctamente, puede hacer una gran diferencia a su rendimiento. En cuanto a las preocupaciones que expresa sobre DRY, solo use métodos de clase u otras formas de funciones para realizar todas las puestas y eliminaciones de sus entidades (es decir, [[excepto dentro de los métodos de clase en cuestión]], nunca llame a métodos como .put() directamente en las entidades, ¡llame a los métodos de clase apropiados en su lugar!), ¡y esas funciones serán el lugar obvio para mantener los contadores desnormalizados actualizados!

Cuestiones relacionadas