编程语言
首页 > 编程语言> > python-ndb模型-检索属性名称的有序集合

python-ndb模型-检索属性名称的有序集合

作者:互联网

我经常被要求将NDB模型中存储的数据导出到csv.为此,我通常最终编写如下模型:

from google.appengine.ext import ndb

class Foo(ndb.Model):
    monty = ndb.StringProperty()
    python = ndb.StringProperty()

    @property
    @classmethod
    def fieldnames(cls):
        return ['monty', 'python']

并在导出模块中

# 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)

请注意,需要使用fieldnames方法来确定输出csv中字段的顺序.这种方法的问题在于,对于任何具有大量属性的模型,添加fieldnames方法都是重复的工作.理想情况下,我想简单地对属性进行声明时对它们进行排序,并以与字段名相同的顺序检索它们.有没有办法按顺序检索这些属性? Foo._properties按字母顺序排序.

解决方法:

据我所知,如果不自己解析源代码,这是不可能的.幸运的是,以python的“含电池”心态,这并不难.您可以使用inspect来获取源代码,然后可以使用ast来解析源并对命令进行排序:

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

注意,这里的方法几乎是通用的.我使用了ndb.Models具有_properties属性的知识,但是该信息可能可以从dir或inspect.getmembers中收集,因此可以修改order_properties使其完全正常工作.

标签:app-engine-ndb,google-app-engine,csv,python
来源: https://codeday.me/bug/20191030/1965444.html