Pregunta

Tengo datos jerárquicos almacenados en el almacén de datos usando un modelo que se ve así:

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

Quiero imprimir todos los nombres de categoría preservando la jerarquía, digamos de alguna forma como esta:

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

Para hacer lo anterior, he usado una recursión simple usando la capacidad de referencia inversa:

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)

Como soy muy nuevo en la programación del motor de aplicaciones (apenas 3 días desde que comencé a escribir código), no estoy seguro de si esta es la forma más optimizada desde el punto de vista de acceso al almacén de datos para hacer el trabajo deseado.

¿Es esta la mejor manera? si no lo que es

¿Fue útil?

Solución

¡Tienes un enfoque muy razonable! Mi advertencia principal sería una que tenga poco que ver con GAE y mucho con Python: no construya una cadena de piezas con + o + = . Por el contrario, haces una lista de piezas de cadena (con append o extender o lista de comprensiones & amp; c) y cuando termines te unes para la cadena final resultado con '' .join (thelist) o similar. Aunque las versiones recientes de Python se esfuerzan por optimizar el rendimiento intrínsecamente O (N cuadrado) de los bucles + o + = , al final usted siempre es mejor construir listas de cadenas en el camino y ''. ¡únete al final!

Otros consejos

La principal desventaja de su enfoque es que está utilizando la " lista de adyacencia " Para representar los árboles, debe realizar una consulta del almacén de datos para cada rama del árbol. Las consultas del almacén de datos son bastante caras (alrededor de 160 ms cada una), por lo que construir el árbol, especialmente si es grande, podría ser bastante caro).

Hay otro enfoque, que es esencialmente el que toma el almacén de datos para representar grupos de entidades: en lugar de simplemente almacenar la clave principal, almacene toda la lista de antepasados ??utilizando ListProperty:

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

Luego, para construir el árbol, puede recuperar todo en una sola consulta:

q = ToolCategories.all().filter('parents =', root_key)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top