如何在GAE Python中获取NDB模型的属性类型

时间:2015-03-01 18:45:48

标签: python google-app-engine google-cloud-datastore

[在问题末尾添加解决方案]

如何在GAE Python中获取NDB模型的属性类型?

示例模型:

class X(ndb.Model): 
    prop_1 = ndb.IntegerProperty ("a", indexed=True) 
    prop_2 = ndb.StringProperty ("b") 
    prop_3 = ndb.DateTimeProperty ("c", repeated=True) 
    prop_4 = ndb.DateProperty ("d", repeated=False)

使用GAE Metadata API没有帮助。

我可以使用get_properties_of_kind(kind)获取模型X的所有属性的列表。

但是get_representations_of_kind(kind)无法帮助我获取属性类型,因为它具有多个属性类型的相同属性表示值(例如DateTimeDate都有{{1} })。

ATTEMPT 1

INT64

输出

y = globals()["X"]  # IF I GET THE MODEL NAME AS STRING; ELSE y = X. 
logging.info (y) 
logging.info (vars(y)) 
for item in vars(y): 
    if (item[0]!="_"):  # ASSUMING ALL INTERNAL KEY NAMES START WITH "_". 
        logging.info ("item=["+item+"] ") 
        logging.info ("vars(y)[item]=["+repr (vars(y)[item])+"] ")

使用这种方法,我会将模型的属性类型作为字符串(例如,2015-03-02 00:08:43.166 +0530 I X<prop_1=IntegerProperty('a'), prop_2=StringProperty('b'), prop_3=DateTimeProperty('c', repeated=True)> 2015-03-02 00:08:43.171 +0530 I {'__module__': '__main__', 'prop_1': IntegerProperty('a'), 'prop_2': StringProperty('b'), 'prop_3': DateTimeProperty('c', repeated=True), '_properties': {'a': IntegerProperty('a'), 'c': DateTimeProperty('c', repeated=True), 'b': StringProperty('b')}, '_has_repeated': True, '__doc__': None} 2015-03-02 00:08:43.186 +0530 I item=[prop_1] 2015-03-02 00:08:43.191 +0530 I vars(y)[item]=[IntegerProperty('a')] 2015-03-02 00:08:43.195 +0530 I item=[prop_2] 2015-03-02 00:08:43.200 +0530 I vars(y)[item]=[StringProperty('b')] 2015-03-02 00:08:43.204 +0530 I item=[prop_3] 2015-03-02 00:08:43.209 +0530 I vars(y)[item]=[DateTimeProperty('c', repeated=True)] )。我必须使用正则表达式提取属性类型(DateTimeProperty('c', repeated=True))。

这是正确的(也是最好的)方法吗?


根据@Greg和@Alex Martelli的回答,我能够找到一个解决方案:

DateTimeProperty

注意我无法使用GAE Metadata API,因为它至少需要一个模型实体才能出现,这在我的情况下是不必要的。
在我的情况下,我需要从字符串创建类名(因此globals()..)。

现在,

仅问题是如何将实际属性名称(如“prop_1”)与获取的属性类型相关联的?现在,短名称(如“a”)映射到属性类型。

如果我做错了,请告诉我。

2 个答案:

答案 0 :(得分:3)

如果存在任何模型类X的实体,我建议:

from google.appengine.ext.ndb import metadata

props = metadata.get_properties_of_kind('X')
prop_to_type = {}
for p in props:
    prop_to_type[p] = type(getattr(X, p))

如果不存在模型类X的实体,props将是空列表,因此您可能不得不采用稍微棘手的方法,例如

props = X._property

在这种情况下,propsdict,其值是属性类的实例 - 但您仍然可以循环props(获取dict的键,它们是属性名称)并使用与上面相同的type(getattr(...代码来获取实际类型。

然而,我仍然认为这个问题有点棘手&#34;因为在Python中,一般认为在可行的情况下避免访问以下划线开头的名称会更好! - )

答案 1 :(得分:1)

如果您有模型类,则其_properties属性将包含属于数据存储区属性的属性。从那里,您可以访问该类的__name__和/或该属性的任何其他属性。

您无需像往常一样访问globals()vars(),也无需使用正则表达式。