Обходной путь для возврата списка из функции ComputedProperty в NDB

Я конвертирую свое приложение для использования NDB. Раньше у меня было что-то вроде этого:

@db.ComputedProperty
    def someComputedProperty(self, indexed=False):
      if not self.someCondition:
          return []
      src = self.someReferenceProperty
      list =  src.list1 + src.list2 + src.list3 + src.list4 \
              + [src.str1, src.str2]
      return map(lambda x:'' if not x else x.lower(), list) 

Как видите, мой метод генерации списка немного сложен, я предпочитаю оставить его таким. Но когда я начал конвертировать в NDB, я просто заменил @db.ComputedProperty на @model.ComputedProperty, но тогда я получил эту ошибку:

NotImplementedError: Property someComputedProperty does not support <type 'list'> types.

Я мог видеть в model.py в ext.ndb, что ComputedProperty наследуется от GenericProperty, где в _db_set_value есть несколько операторов if/else, которые обрабатывают значение в соответствии с его типом, за исключением того, что нет обработки для lists

В настоящее время он проходит первое условие и выдает эту ошибку, когда я возвращаю пустой список.

Есть ли способ обойти это и избежать ошибки?


person Mohamed Khamis    schedule 17.01.2012    source источник
comment
Предоставление indexed=False вашей функции в первом фрагменте не влияет на индексацию вашего вычисляемого свойства. Как отмечает Мохамед Хамис, если вы не хотите, чтобы он индексировался, то нет смысла вообще хранить его в хранилище данных — просто используйте обычный @Property.   -  person Nick Johnson    schedule 18.01.2012


Ответы (2)


Вам необходимо установить флаг Repeat=True для вашего вычисляемого свойства в NDB. Я не думаю, что вы можете использовать симпатичную нотацию "@db.ComputedProperty", вам придется сказать:

def _computeValue(self):
    ...same as before...
someComputedProperty = ComputedProperty(_computeValue, repeated=True, indexed=False)
person Guido van Rossum    schedule 18.01.2012

Вся эта функциональность может быть реализована внутри функции, поэтому она не обязательно должна быть ComputedProperty. Используйте вычисляемые свойства только тогда, когда вы хотите выполнить вычисление, которое вы можете запросить. ComputedProperty может иметь свой флаг indexed, установленный в False, но тогда это означает, что вы не будете запрашивать его, и, следовательно, вам не нужно иметь его как свойство.

def someComputedProperty(self):
  if not self.someCondition:
      return []
  src = self.someReferenceProperty
  list =  src.list1 + src.list2 + src.list3 + src.list4 \
          + [src.str1, src.str2]
  return map(lambda x:'' if not x else x.lower(), list) 
person Mohamed Khamis    schedule 17.01.2012
comment
Это верно, если только вы не собираетесь писать запросы к этому свойству... тогда вам понадобится ComputedProperty, чтобы он находился в хранилище данных. - person TM.; 03.03.2015
comment
В целом согласен, но может быть странный случай, когда вы просто не хотите запрашивать его, но хотите видеть его в средстве просмотра хранилища данных. - person Bemmu; 13.04.2018