我正在尝试从展示如何使用App Engine Search API的示例应用中了解this code snippet:
rid = models.Review.allocate_ids(size=1)[0]
key = ndb.Key(models.Review._get_kind(), rid)
def _tx():
review = models.Review(
key=key,
product_key=prod.key,
username=username, rating=rating,
comment=comment)
review.put()
# in a transactional task, update the parent product's average
# rating to include this review's rating, and flag the review as
# processed.
defer(utils.updateAverageRating, key, _transactional=True)
return review
return ndb.transaction(_tx)
所以基本上它会为产品创建一个Review实体,并添加一个延迟任务来更新该产品的平均评级。我有两个问题:
allocate_ids()
方法。这个更简单的替代方案也不会起作用吗?def _tx():
review = models.Review(
product_key=prod.key,
username=username, rating=rating,
comment=comment)
review.put()
# in a transactional task, update the parent product's average
# rating to include this review's rating, and flag the review as
# processed.
defer(utils.updateAverageRating, review.key, _transactional=True)
return review
return ndb.transaction(_tx)
答案 0 :(得分:1)
我也不明白。据我所知,绝对没有理由在交易之外手动分配密钥。 model.put()
返回实体的密钥,您也可以从实例中获取它(就像您在示例中所做的那样)。如果put()
是异步的,我可以看到逻辑(虽然我不会这样做),但事实并非如此。
这项交易似乎没有任何合理的理由。如果您只使用不依赖于已保留到数据存储区的数据的数据更新单个实体,则不需要事务。我能想到的唯一原因是确保仅在事务成功应用时才运行延迟任务,但由于没有真正的理由首先处理事务,您可以摆脱它并跳过添加延迟任务写操作失败。