Domanda

Ho dei dati gerarchici archiviati nell'archivio dati usando un modello simile al seguente:

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

Voglio stampare tutti i nomi delle categorie preservando la gerarchia, diciamo in una forma come questa:

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

Per fare quanto sopra ho usato una semplice ricorsione usando la capacità di referenziamento di ritorno:

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)

Dato che sono molto nuovo nella programmazione del motore dell'app (quasi 3 giorni da quando ho iniziato a scrivere il codice), non sono sicuro che questo sia il modo più ottimizzato dal punto di vista dell'accesso a Datastore per fare il lavoro desiderato.

È questo il modo migliore? se non ciò che è?

È stato utile?

Soluzione

Hai un approccio molto ragionevole! Il mio avvertimento principale sarebbe quello che ha poco a che fare con GAE e molto con Python: non costruire una stringa da pezzi con + o + = . Piuttosto, fai un elenco di pezzi di stringa (con append o extender o comprendi la lista & amp; c) e quando hai finito ti unisci per la stringa finale risultato con '' .join (lista) o simili. Anche se le recenti versioni di Python si impegnano a fondo per ottimizzare intrinsecamente le prestazioni O (N al quadrato) dei loop + o + = , alla fine tu stai sempre meglio costruendo elenchi di stringhe lungo il percorso e '' .join inserendoli alla fine!

Altri suggerimenti

Il principale svantaggio del tuo approccio è che, poiché stai utilizzando l'elenco di adiacenza " per rappresentare gli alberi, è necessario eseguire una query di archivio dati per ciascun ramo dell'albero. Le query sui datastore sono piuttosto costose (circa 160 ms ciascuna), quindi costruire l'albero, in particolare se è grande, potrebbe essere piuttosto costoso).

Esiste un altro approccio, che è essenzialmente quello adottato dall'archivio dati per rappresentare i gruppi di entità: invece di archiviare solo la chiave padre, memorizzare l'intero elenco di antenati usando ListProperty:

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

Quindi, per costruire l'albero, puoi recuperare l'intera cosa in un'unica query:

q = ToolCategories.all().filter('parents =', root_key)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top