gsinha gsinha - 11 months ago 42
Python Question

How to to get Property Types of a NDB Model in GAE Python

[Added Solution at the end of question]

How to to get Property Types of a NDB Model in GAE Python ?

Example model :

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)

Using GAE Metadata API did not help.

I can get list of all properties of model
using get_properties_of_kind(kind).

But get_representations_of_kind(kind) would not help me get the property types as it has the same property representation values for more than one property type ( like
both have


y = globals()["X"] # IF I GET THE MODEL NAME AS STRING; ELSE y = X. (y) (vars(y))
for item in vars(y):
if (item[0]!="_"): # ASSUMING ALL INTERNAL KEY NAMES START WITH "_". ("item=["+item+"] ") ("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)]

Using this approach, I would get the Property Types of a Model as String ( like,
DateTimeProperty('c', repeated=True)
). I would have to extract the Property Type (
) using regex.

Is this the correct ( and the best ) way to do it ?


Based on answers by @Greg and @Alex Martelli, I was able to come up with a solution :

obj = globals ()["X"]
for item in obj._properties: ("b item=["+item+"] ")
# This gave the short names of properties : "a", "b", "c", .. ("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]!="_"): ("HB item=["+item+"] ")
# This gave the actual property name : "prop_1", "prop_2", "prop_3", ..

Note that I could not use the GAE Metadata API since it needs at least one entity of the Model to be present, which is not necessary in my case.

In my situation, I need to create the class name from string ( hence the globals().. ).

Only problem, now, is how to correlate actual property names ( like "prop_1" ) to the obtained property types ? Right now, the short names ( like "a" ) map to property types.

Please let me know if I am doing something wrong.

Answer Source

If you have a model class, then its _properties attribute will contain the attributes that are datastore-properties. From there, you can access the __name__ of the class and/or any other attributes of the Property.

You don't need to be accessing globals() or vars() like you're doing, and there's definitely no need to resort to regex.