如何在 GAE Python 中获取 属性 NDB 模型的类型
How to to get Property Types of a NDB Model in GAE Python
[在问题末尾添加解决方案]
如何在 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) 不会帮助我获得 属性 类型,因为它对多个 属性 类型具有相同的 属性 表示值(例如 DateTime
和 Date
都有 INT64
)。
尝试 1
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)
)。我将不得不使用正则表达式提取 属性 类型( DateTimeProperty
)。
这是正确的(也是最好的)方法吗?
解决方案
根据@Greg 和@Alex Martelli 的回答,我想出了一个解决方案:
obj = globals ()["X"]
for item in obj._properties:
logging.info ("b item=["+item+"] ")
# This gave the short names of properties : "a", "b", "c", ..
logging.info ("b needed part = ["+obj._properties[item].__class__.__name__+"] ")
# This gave the property type class : "IntegerProperty", "StringProperty", "DateTimeProperty", ..
for item in obj.__dict__:
if (item[0]!="_"):
logging.info ("HB item=["+item+"] ")
# This gave the actual property name : "prop_1", "prop_2", "prop_3", ..
注意 我不能使用 GAE Metadata API 因为它需要至少一个模型实体存在,这对我来说不是必需的。
在我的情况下,我需要从字符串创建 class 名称(因此是 globals().. )。
现在唯一的问题是如何将实际的 属性 名称(如 "prop_1" )与获得的 属性 类型相关联?现在,短名称(如 "a" )映射到 属性 类型。
如果我做错了什么,请告诉我。
如果您有一个模型 class,那么它的 _properties
属性将包含数据存储属性。从那里,您可以访问 class 的 __name__
and/or 属性 的任何其他属性。
您不需要像现在这样访问 globals()
或 vars()
,而且绝对没有必要求助于正则表达式。
如果模型 class 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))
如果不存在模型 class X
的实体,props
将是空列表,因此您可能不得不求助于稍微棘手的方法,例如
props = X._property
在这种情况下,props
是一个 dict
,它的值是 属性 classes 的 个实例 - - 但你仍然可以在 props
上循环(获取字典的键,即 属性 名称)并使用与上面相同的 type(getattr(...
代码来获取实际类型。
我仍然考虑这个 "slightly trickier" 因为在 Python 中,通常认为在可行的情况下最好避免访问以下划线开头的名称!-)
[在问题末尾添加解决方案]
如何在 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) 不会帮助我获得 属性 类型,因为它对多个 属性 类型具有相同的 属性 表示值(例如 DateTime
和 Date
都有 INT64
)。
尝试 1
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)
)。我将不得不使用正则表达式提取 属性 类型( DateTimeProperty
)。
这是正确的(也是最好的)方法吗?
解决方案
根据@Greg 和@Alex Martelli 的回答,我想出了一个解决方案:
obj = globals ()["X"]
for item in obj._properties:
logging.info ("b item=["+item+"] ")
# This gave the short names of properties : "a", "b", "c", ..
logging.info ("b needed part = ["+obj._properties[item].__class__.__name__+"] ")
# This gave the property type class : "IntegerProperty", "StringProperty", "DateTimeProperty", ..
for item in obj.__dict__:
if (item[0]!="_"):
logging.info ("HB item=["+item+"] ")
# This gave the actual property name : "prop_1", "prop_2", "prop_3", ..
注意 我不能使用 GAE Metadata API 因为它需要至少一个模型实体存在,这对我来说不是必需的。
在我的情况下,我需要从字符串创建 class 名称(因此是 globals().. )。
现在唯一的问题是如何将实际的 属性 名称(如 "prop_1" )与获得的 属性 类型相关联?现在,短名称(如 "a" )映射到 属性 类型。
如果我做错了什么,请告诉我。
如果您有一个模型 class,那么它的 _properties
属性将包含数据存储属性。从那里,您可以访问 class 的 __name__
and/or 属性 的任何其他属性。
您不需要像现在这样访问 globals()
或 vars()
,而且绝对没有必要求助于正则表达式。
如果模型 class 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))
如果不存在模型 class X
的实体,props
将是空列表,因此您可能不得不求助于稍微棘手的方法,例如
props = X._property
在这种情况下,props
是一个 dict
,它的值是 属性 classes 的 个实例 - - 但你仍然可以在 props
上循环(获取字典的键,即 属性 名称)并使用与上面相同的 type(getattr(...
代码来获取实际类型。
我仍然考虑这个 "slightly trickier" 因为在 Python 中,通常认为在可行的情况下最好避免访问以下划线开头的名称!-)