Question

Les données hiérarchiques stockées dans le magasin de données utilisent un modèle ressemblant à ceci:

class ToolCategories(db.Model):  
   name = db.StringProperty()  
   parentKey = db.SelfReferenceProperty(collection_name="parent_category")  
   ...  
   ...  

Je souhaite imprimer tous les noms de catégorie en préservant la hiérarchie, par exemple sous une forme semblable à celle-ci:

--Information Gathering  
----OS Fingerprinting  
----DNS  
------dnstool  
----Port Scanning   
------windows  
--------nmap  
----DNS3  
----wireless sniffers  
------Windows  
--------Kismet  

Pour faire ce qui précède, j'ai utilisé une récursivité simple à l'aide de la fonctionnalité de référencement arrière:

class GetAllCategories (webapp.RequestHandler) :


        def RecurseList(self, object, breaks) :
                output = breaks + object.name + "</br>"
                for cat in object.parent_category:
                        output = output + self.RecurseList(cat, breaks + "--")

                return output



        def get (self) :
                output = ""
                allCategories = ToolCategories.all().filter(' parentKey = ', None)
                for category in allCategories :
                        output = output + self.RecurseList(category, "--")

                self.response.out.write(output)

Comme je suis très novice dans la programmation des moteurs d’applications (trois jours à peine depuis que j’ai commencé à écrire du code), je ne sais pas si c’est le moyen le plus optimisé du point de vue de l’accès au magasin de données pour effectuer le travail souhaité.

Est-ce le meilleur moyen? sinon ce qui est?

Était-ce utile?

La solution

Vous avez une approche très raisonnable! Mon avertissement principal est celui qui a peu à voir avec GAE et beaucoup avec Python: ne pas construire une chaîne à partir de morceaux avec + ou + = . Au lieu de cela, vous faites une liste de morceaux de chaîne (avec append ou extend ou une liste de compréhensions & amp; c) et lorsque vous avez tous terminé, vous le rejoignez pour la chaîne finale. résultat avec ''. join (liste) ou similaire. Même si les versions récentes de Python s'efforcent d'optimiser les performances intrinsèques O (N carré) des boucles + ou + = , à la fin Il est toujours préférable de constituer des listes de chaînes le long du chemin et ''. Rejoignez-les en les intégrant à la fin!

Autres conseils

Le principal inconvénient de votre approche est que vous utilisez la " liste de contiguïté " Pour représenter les arbres, vous devez effectuer une requête de banque de données pour chaque branche de l’arbre. Les requêtes de banque de données sont assez coûteuses (environ 160 ms chacune), donc la construction de l'arborescence, particulièrement si elle est volumineuse, pourrait être assez coûteuse).

Il existe une autre approche, qui est essentiellement celle prise par le magasin de données pour représenter les groupes d'entités: au lieu de simplement stocker la clé parente, stockez toute la liste des ancêtres à l'aide d'un ListProperty:

class ToolCategories(db.Model):
  name = db.StringProperty()
  parents = db.ListProperty(db.Key)

Ensuite, pour construire l’arborescence, vous pouvez récupérer le tout en une seule requête:

q = ToolCategories.all().filter('parents =', root_key)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top