2010-07-12 7 views
5

Quelle est la meilleure façon de déterminer le nombre de modèles d'un certain type dans le magasin de données de mon application? La documentation dit que MyKind.all().count() est seulement légèrement meilleure que la récupération de toutes les données, et a une limite de 1000. Ce n'est pas utile, car je m'attends à avoir plus de 6000 instances de MyKind stockées.GAE: Meilleure façon de déterminer combien d'exemplaires sont stockés?

Y a-t-il une meilleure façon de procéder? Que se passe-t-il si je reçois les clés et les compte? J'utilise Python. J'utilise Python.

+0

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

Répondre

1

Conservez un objet compteur pour votre application stocké dans la base de données et mettez-le à jour chaque fois que vous créez et supprimez des objets.

+0

C'est une sorte d'une douleur. Ce n'est pas SEC, et maintenant je dois aller chercher partout dans le code pour trouver n'importe quel moment où 'MyKind' est créé ou supprimé. –

+2

@Rosarch Si les instances de 'MyKind' sont' put() 'partout dans votre code, votre conception pourrait bénéficier d'une application plus cohérente de DRY. :-) –

3

Si vous faites des touches seulement il devrait être assez rapide, car il suffit de lire l'index et doesn ne récupère aucune entité. Utilisez un curseur et boucle jusqu'à ce que le nombre() retourne moins de 1000.

2

This SO question a une réponse (par @jgeewax) qui est presque droite (mauvais état de sortie, comme je l'ai commenté là-bas). Voici un fixe ...:

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 

Le problème de performance, bien sûr, est que cela utilisera une requête réelle au magasin de données pour tous les 1000 articles que vous avez - les choses dénormaliser en gardant un nombre réel, comme le suggère @Chris, va utiliser lointain moins de requêtes. (Assurez-vous d'utiliser un sharded counter ou d'autres formes de efficient counters en tant que ventilateur App Engine explique!).

La dénormalisation est une réalité de la vie avec des bases de données non relationnelles, et, faite correctement, peut faire une différence de énorme à votre performance. En ce qui concerne les soucis que vous exprimez sur DRY, utilisez simplement des méthodes de classe ou d'autres formes de fonctions pour effectuer toutes les opérations de suppression et de suppression de vos entités (par exemple, [sauf les méthodes de classe en question]]. directement sur les entités, appelez les méthodes de classe appropriées à la place!), et ces fonctions seront l'endroit évident pour garder les compteurs dénormalisés à jour!

Questions connexes