2010-08-16 4 views
0

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

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

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

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

То, что вы хотите это 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) 

Поскольку операция прибудете и условная вставка происходят в транзакции, состояние гонки не представляется возможным.

Смежные вопросы