Получить существующий или создать новый синтаксис App Engine - PullRequest
0 голосов
/ 16 августа 2010

Я наткнулся на этот синтаксис, просматривая код для примеров. Из окружающего кода это выглядело бы так: a) получить объект с заданным именем ключа или b) , если объект не существует, создать новый объект, который можно сохранить. Предположим, мой модельный класс называется MyModel.

my_model = MyModel(key_name='mymodelkeyname', 
                   kwarg1='first arg', kwarg2='second arg')

У меня сейчас проблемы, но только в определенных ситуациях. Мое предположение о том, что этот фрагмент исправляет? Или я всегда должен делать следующее?

my_model = MyModel.get_by_key_name('mymodelkeyname')
if not my_model:
    my_model = MyModel(key_name='mymodelkeyname', 
                       kwarg1='first arg', kwarg2='second arg')
else:
    # do something with my_model

Ответы [ 2 ]

2 голосов
/ 16 августа 2010

Конструктор, который вы используете, всегда создает новую сущность.Когда вы сохраняете его, он перезаписывает любой другой объект с тем же ключом.

Альтернативный код, который вы предлагаете, также имеет проблему: он подвержен условиям гонки.Два экземпляра этого кода, выполняющиеся одновременно, могут оба определить, что сущность не существует, и каждый ее создать, в результате чего один перезаписывает работу другого.

То, что вам нужно, это Model.get_or_insert метод, который является синтаксическим сахаром для этого:

def get_or_insert(cls, key_name, **kwargs):
  def _tx():
    model = cls.get_by_key_name(key_name)
    if not model:
      model = cls(key_name=key_name, **kwargs)
      model.put()
    return model
  return db.run_in_transaction(_tx)

Поскольку операция get и условная вставка выполняются в транзакции, условие состязания невозможно.

1 голос
/ 16 августа 2010
...