获取现有或创建新的App Engine语法

时间:2010-08-16 01:54:18

标签: python google-app-engine models modeling

我遇到了这种语法浏览代码示例。从其周围的代码看,似乎 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 个答案:

答案 0 :(得分: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)

由于get操作和条件插入发生在事务中,因此无法进行竞争条件。

答案 1 :(得分:1)