Массовые обновления в хранилище данных Google App Engine - PullRequest
11 голосов
/ 20 ноября 2011

Как правильно выполнять массовые обновления сущностей в хранилище данных Google App Engine?Можно ли это сделать без необходимости извлечения сущностей?

Например, что будет эквивалентно GAE чему-то подобному в SQL:

UPDATE dbo.authors
SET    city = replace(city, 'Salt', 'Olympic')
WHERE  city LIKE 'Salt%';

Ответы [ 3 ]

9 голосов
/ 20 ноября 2011

Прямого перевода нет.В хранилище данных действительно нет концепции обновлений;все, что вы можете сделать, это перезаписать старые сущности новой сущностью по тому же адресу (ключу).Чтобы изменить объект, вы должны извлечь его из хранилища данных, изменить его локально, а затем сохранить обратно.

Также нет эквивалента оператору LIKE.Хотя сопоставление суффиксов с подстановочными знаками возможно с некоторыми хитростями, если вы хотите сопоставить «% Salt%», вам придется читать каждую отдельную сущность в память и выполнять сравнение строк локально.

Так что это не будетстоль же чистый или эффективный как SQL.Это компромисс с большинством распределенных хранилищ объектов, и хранилище данных не является исключением.

Тем не менее, библиотека картографирования доступна для облегчения таких пакетных обновлений.Следуйте примеру и используйте что-то подобное для вашей process функции:

def process(entity):
  if entity.city.startswith('Salt'):
    entity.city = entity.city.replace('Salt', 'Olympic')
    yield op.db.Put(entity)

Есть и другие альтернативы, кроме картографа.Самый важный совет по оптимизации - это пакетные обновления;не сохраняйте обратно каждый обновленный объект индивидуально.Если вы используете маппер и put yield, это обрабатывается автоматически.

5 голосов
/ 20 ноября 2011

Нет, это невозможно сделать без извлечения сущностей.

Не существует такого понятия, как «максимальный предел записи 1000», но, конечно, для любого отдельного запроса существует тайм-аут - и если у вас есть большое количество сущностей для изменения, простая итерация, вероятно, не справится с этой задачей. Вы можете справиться с этим, разделив его на несколько операций и отслеживая с помощью курсора запроса или, возможно, используя MapReduce framework .

2 голосов
/ 20 ноября 2011

вы можете использовать класс запроса, http://code.google.com/appengine/docs/python/datastore/queryclass.html

 query = authors.all().filter('city >', 'Salt').fetch()
 for record in query:
   record.city = record.city.replace('Salt','Olympic')
...