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