Ndb-Modell – abgerufenen Satz von Eigenschaftsnamen abrufen

Ich werde oft aufgefordert, in NDB-Modellen gespeicherte Daten in csv zu exportieren. Zu diesem Zweck habe ich meistens ein Modell wie folgt geschrieben:

from google.appengine.ext import ndb class Foo(ndb.Model): monty = ndb.StringProperty() python = ndb.StringProperty() @property @classmethod def fieldnames(cls): return ['monty', 'python'] 

Und im Exportmodul etwas entlang der Linien von

 # pseudocode ... query = Foo.gql('where monty = :1', 'bunny') data = [littlefoo._to_dict() for littlefoo in query] fieldnames = Foo.fieldnames with open('outfile.csv', 'w') as f: writer = csv.DictWriter(f, fieldnames, dialect=dialect) writer.writerows(data) 

Beachten Sie, dass die Feldname-Methode benötigt wird, um die Reihenfolge der Felder in der Ausgabe csv zu bestimmen. Das Problem mit diesem Ansatz ist, dass für jedes Modell mit einer signifikanten Anzahl von Attributen, Hinzufügen der fieldnames Methode ist hässlich duplizieren Arbeit. Im Idealfall möchte ich einfach die Eigenschaften bestellen, wie ich sie erkläre und sie in der gleichen Reihenfolge für fieldnames . Gibt es eine Möglichkeit, diese Eigenschaften in der Reihenfolge abzurufen? Foo._properties ist alphabetisch geordnet.

2 Solutions collect form web for “Ndb-Modell – abgerufenen Satz von Eigenschaftsnamen abrufen”

Meines Wissens ist dies nicht möglich, ohne die Quelle für sich selbst zu analysieren. Zum Glück, mit Python's "Batterien enthalten" Mentalität, das ist nicht zu schwer. Sie können inspect , um den Quellcode zu erhalten, und dann können Sie ast , um die Quelle zu analysieren und Dinge zu bestellen:

 import ast import inspect class NodeTagger(ast.NodeVisitor): def __init__(self): self.class_attribute_names = {} def visit_Assign(self, node): for target in node.targets: self.class_attribute_names[target.id] = target.lineno # Don't visit Assign nodes inside Function Definitions. def visit_FunctionDef(self, unused_node): return None def order_properties(model): properties = model._properties source = inspect.getsource(model) tree = ast.parse(source) visitor = NodeTagger() visitor.visit(tree) attributes = visitor.class_attribute_names model._ordered_property_list = sorted(properties, key=lambda x:attributes[x]) return model @order_properties class Foo(object): c = 1 b = 2 a = 3 # Add a _properties member to simulate an `ndb.Model`. _properties = {'a': object, 'b': object, 'c': object} print Foo._ordered_property_list 

Beachten Sie, dass der Ansatz hier fast allgemein ist. Ich habe das Wissen benutzt, dass ndb.Model s ein _properties Attribut haben, aber diese Information könnte vermutlich von dir oder inspect.getmembers order_properties werden, so dass inspect.getmembers order_properties konnten, damit es ganz allgemein funktioniert.

Ich mache das gerade aus, es ist wahrscheinlich voller Fehler, aber hoffentlich geht es dich auf den richtigen Weg:

 from google.appengine.ext.ndb import Property def get_field_names(ndbmodel): result = [] all_fields = dir(ndbmodel) for field in all_fields: if isinstance(getattr(ndbmodel, field), Property): result.append(field) return result.sort() 
  • Facebook Logout mit OAuth Server Seite
  • Import webapp2 funktioniert auf google-app-engine, obwohl ich kein webapp2 installiert habe
  • Wie kann man Daten aus dem Google-App-Engine herunterladen
  • Google App Engine Python Webapp2 301 Umleitung von www zu non-www Domain
  • High-Parallelität Zähler ohne Scherbe
  • DeadlineExceededError konnte nicht mit UrlFetch verarbeitet werden
  • Bewerte eine Bedingung nach put () in NDB und GAE
  • Wie kann ich bcrypt / scrypt auf appengine für Python verwenden?
  • In Python in Google App Engine, wie erfassen Sie die von der print-Anweisung erzeugte Ausgabe?
  • Entdecken Sie den Discovery-Pfad auf dem App Engine Module
  • Optionaler URL-Parameter in Route GAE webapp2
  • Python ist die beste Programmiersprache der Welt.