Расширение базы данных appengine с помощью кеширования - PullRequest
0 голосов
/ 13 марта 2010

Я хочу реализовать класс свойств для appengine, очень похожий на существующий db.ReferenceProperty. Я реализую свою собственную версию, потому что я хочу некоторые другие возвращаемые значения по умолчанию. Мой вопрос: как заставить свойство запомнить возвращаемое значение, чтобы запрос хранилища данных выполнялся только при первом получении свойства? То, что у меня было ниже, и это не работает. Я прочитал, что классы Property принадлежат не экземплярам, ​​а определению модели, поэтому я предполагаю, что возвращаемое значение не кэшируется для каждого экземпляра, а каждый раз перезаписывается в модели. Где должен Я храню эту _resolved переменную?

class PageProperty(db.Property):
  data_type = Page

  def get_value_for_datastore(self, model_instance):
    page = super(PageProperty, self).get_value_for_datastore(model_instance)        
    self._resolved = page
    return page.key().name()

  def make_value_from_datastore(self, value):
    if not hasattr(self, '_resolved'):
        self._resolved = Page.get_by_name(value)
    return self._resolved

Редактировать

Ответ Алекса, безусловно, пригоден для использования. Но, похоже, что встроенная db.ReferenceProperty действительно сохраняет переменную _RESOLVED в экземпляре модели. Как свидетельствуют:

[...]
    setattr(model_instance, self.__resolved_attr_name(), value)
[...]

def __resolved_attr_name(self):
    return '_RESOLVED' + self._attr_name()

Метод get_value_for_datastore передается экземпляру модели, но make_value_from_datastore нет, так как они находят свойство _RESOLVED из этого метода?

Редактировать 2

Из кода я понял, что Google использует методы __get__() и __set__(), которые оба получают экземпляр модели в качестве аргумента. Это можно использовать в пользовательских классах? В чем разница с get_value_for_datastore и его аналогом?

Ответы [ 2 ]

2 голосов
/ 13 марта 2010

A PageProperty экземпляр существует для каждой модели, а не для каждой сущности (где сущность является экземпляром класса модели). Поэтому я думаю, что вам нужен словарь , который отображает сущность pagename -> Page, а не один атрибут для экземпляра PageProperty. Например, может быть что-то вроде ...:

class PageProperty(db.Property):
  data_type = Page

  def __init__(self, *a, **k):
    super(PageProperty, self).__init__(*a, **k)
    self._mycache = {}       

  def get_value_for_datastore(self, model_instance):
    page = super(PageProperty, self).get_value_for_datastore(model_instance)        
    name = page.key().name()
    self._mycache[name] = page
    return name

  def make_value_from_datastore(self, value):
    if value not in self._mycache:
        self._mycache[value] = Page.get_by_name(value)
    return self._mycache[value]
1 голос
/ 15 марта 2010

Если вы хотите изменить только небольшую часть поведения ReferenceProperty, вы можете просто расширить его, переопределив метод default_value . Вы можете найти источник для ReferenceProperty поучительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...