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() 
  • Wie greifen Sie von einem (Nicht-Web) -Python-Client auf einen authentifizierten Google App Engine-Dienst zu?
  • Python kann nicht auf POST auf html
  • Pubnub Präsenz in Python (GAE)
  • Speichern Sie eine Liste der Wörterbücher in GAE
  • Mit weniger Datenspeicher kleine Operationen in Appengine
  • Importieren Sie benutzerdefiniertes Paket in python Google App-Engine
  • Wie man doppelte Daten in meinem Datenspeicher überprüft und den Fehler anzeigt?
  • Importieren von Sqlite-Daten in Google App Engine
  • Python / WebApp Google App Engine - Test für Benutzer / Pass in den Headern
  • Warum wird dieses Bild nicht angezeigt (defektes Bildsymbol)?
  • Python Mechanize + GAEpython Code
  • Python ist die beste Programmiersprache der Welt.