2015-03-01 2 views
0

[Добавлено решение в конце вопроса]Как получить Типы свойства ОПРСА модели в GAE Python

Как получить Типы свойства ОПРСА модели в GAE Python?

Пример модели:

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 не помогло.

Я могу получить список всех свойств модели X, используя get_properties_of_kind(kind).

Но 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)). Мне нужно было бы извлечь Property Type (DateTimeProperty) с помощью regex.

Это правильный (и лучший) способ сделать это?

РЕШЕНИЕ
на основе ответов по @Greg и @Alex Мартелли, я был в состоянии придумать решение:

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, поскольку она нуждается по крайней мере, одно лицо Модели должно присутствовать, что не обязательно в моем случае.
В моей ситуации мне нужно создать имя класса из строки (следовательно, globals() ..).

Только проблема, теперь, как соотнести фактические имена свойств (например, «prop_1») с полученными свойствами? Прямо сейчас короткие имена (например, «a») сопоставляются с типами свойств.

Пожалуйста, дайте мне знать, если я делаю что-то неправильно.

ответ

1

Если у вас есть класс модели, то его атрибут _properties будет содержать атрибуты, которые являются свойствами хранилища данных. Оттуда вы можете получить доступ к __name__ класса и/или любым другим атрибутам свойства.

Вам не обязательно обращаться к globals() или vars(), как вы делаете, и вам не обязательно прибегать к регулярному выражению.

+0

Спасибо. Я обновил вопрос с помощью решения. Пожалуйста, дайте мне знать ваши взгляды. – gsinha

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 

В этом случае props является dict, и его значение экземпляров из классы свойств - но вы все еще можете использовать цикл props (получение ключей dict, которые являются именами свойств) и использовать тот же код type(getattr(..., как указано выше, для получения фактических типов.

я все же считаю, что это «немного сложнее», потому что в Python это обычно считается лучше, чтобы избежать доступа имена, которые начинаются с символа подчеркивания, когда это возможно -!)

+0

Спасибо за ваш ответ. Я обновил вопрос с помощью решения. Пожалуйста, дайте мне знать, если это не правильный подход. – gsinha

+1

@gsinha, 'obj = globals() [" X "]' не имеет смысла - 'obj = X' эквивалентен и намного проще и понятнее. Другая критика вашего решения уже выражена в моем ответе, на который вы комментируете, и я не буду повторять их без необходимости. Тем не менее, ваш код должен работать - пока этого не произойдет, а затем, получив удовольствие, отлаживает его :-). –

+0

Я искренне ценю, что вы нашли время, чтобы ответить еще раз. Я реализовал резервное копирование + восстановление объектов GAE в файлы GCS с использованием дампов json (и обрабатывать несериализуемые типы, такие как datetime). При восстановлении объектов после потери данных в NDB не может быть какой-либо сущности этой модели. Для воссоздания сущности, в общем случае для всех моделей, мне нужно будет прочитать имена свойств и назначить значения из файла GCS (json load). В файле GCS все («имя модели», «имена свойств», значения) - «строка». Следовательно, косвенный путь 'obj = globals() [" X "]' вместо 'obj = X'. – gsinha

Смежные вопросы