Pergunta

Eu tenho dados hierárquicos armazenados no armazenamento de dados usando um modelo que se parece com isso:

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

Quero imprimir todos os nomes das categorias preservar a hierarquia, dizer de alguma forma como este:

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

Para fazer a recursão simples acima eu usei usando a capacidade de fazer referência a volta:

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 eu sou muito novo para programação do App Engine (quase 3 dias desde que eu comecei a escrever código), eu não tenho certeza se isso da maneira mais otimizada do acesso ponto de vista do armazenamento de dados para fazer o trabalho desejado.

Esta é a melhor maneira? se não o que é?

Foi útil?

Solução

Você tem uma abordagem muito razoável! Meu principal ressalva seria aquele que tem pouco a ver com GAE e muito com Python: não construir uma string de peças com + ou +=. Em vez disso, você fazer uma lista de peças de cordas (com append ou extend ou compreensões lista & c) e quando estiver tudo pronto você juntar-lo para o resultado seqüência final com ''.join(thelist) ou similar. Mesmo que as versões recentes do Python se esforçam muito para otimizar o desempenho intrinsecamente O(N squared) dos + ou += loops, no final você está sempre melhor construir listas de cordas ao longo do caminho e ''.joining-los no final!

Outras dicas

A principal desvantagem da sua abordagem é que porque você está usando o modo "lista de adjacência" de representar árvores, você tem que fazer um armazenamento de dados de consulta para cada ramo da árvore. Armazenamento de dados consultas são bastante caros (cerca de 160ms cada), de modo que a construção da árvore, especialmente se for grande, poderia ser bastante caro).

Há uma outra abordagem, que é essencialmente a uma tomada pelo armazenamento de dados para representar grupos de entidade: em vez de apenas armazenar a chave pai, armazenar toda a lista de ancestrais usando um ListProperty:

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

Então, para construir a árvore, você pode recuperar a coisa toda em uma única consulta:

q = ToolCategories.all().filter('parents =', root_key)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top