Подтвердить что ты не робот

Список ссылок в Google App Engine для Python

В Google App Engine есть такая вещь, как ListProperty, которая позволяет хранить список (массив) элементов. Вы также можете указать тип удерживаемого элемента, например string, integer или что-то еще.

Google App Engine также позволяет вам иметь ReferenceProperty. ReferenceProperty "содержит" ссылку на другую модель модели Google App Engine. Если вы обратитесь к ReferenceProperty, он автоматически получит фактическую сущность, на которую ссылаются ссылки. Это удобно, поскольку он бьет получение ключа, а затем получает объект для указанного ключа.

Однако я не вижу такой вещи, как ListReferenceProperty (или ReferenceListProperty). Я хотел бы провести список ссылок на другие объекты, которые будут автоматически разрешены при попытке доступа к элементам в списке. Самое близкое, что я могу получить, похоже, состоит в том, чтобы удерживать список объектов db.Key. Я могу использовать эти ключи, а затем вручную извлекать связанные с ними объекты с сервера.

Есть ли хорошее решение? В принципе, я хотел бы иметь возможность иметь набор ссылок (для автоматического разыменования) для других объектов. Я почти добираюсь туда, имея набор ключей к другим объектам, но я хотел бы, чтобы он "знал", что это ключевые элементы, и что он может разыменовать их как услугу для меня.

Спасибо

4b9b3361

Ответ 1

Шаг первый:

Используйте db.ListProperty(db.Key) для создания отношения. Вы хотите, чтобы ListProp был в Entity, который будет иметь меньшее количество ссылок в отношениях Many to Many. Это также даст вам обратную ссылку. Итак:

class Spam
  prop1 = db.String
  eggs = db.List

class Eggs
  prop1 = db.string
  @property
  def spams(self):
    return Spam.all().filter('eggs', self.key())

Это дает ссылки в обоих направлениях.

Шаг второй:

Создайте метод utlility, который устраняет свойства.

def prefetch_refprops(entities, *props):
    """Dereference Reference Properties to reduce Gets.  See:
    http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine
    """
    fields = [(entity, prop) for entity in entities for prop in props]
    ref_keys = [prop.get_value_for_datastore(x) for x, prop in fields]
    ref_entities = dict((x.key(), x) for x in db.get(set(ref_keys)))
    for (entity, prop), ref_key in zip(fields, ref_keys):
        prop.__set__(entity, ref_entities[ref_key])
    return entities  

Использование:

derefrenced_spams = prefetch_refprops(Spams, models.Spam.eggs)    

Ответ 2

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

Однако вы можете использовать db.ListProperty(db.Key), который позволяет вам хранить список ключей. Затем вы можете загрузить их по отдельности или сразу, используя пакетную операцию db.get(). Это требует, чтобы вы сами делали шаг разрешения, но он также дает вам больше контроля при разыменовании объектов.