Model.get_or_insert()如何成为app引擎中的祖先事务

时间:2012-03-07 15:29:41

标签: python google-app-engine transactions bigtable

我不明白python的Model.get_or_insert(key_name, **kwds)方法的google app引擎是如何工作的。

据我了解,事务中的所有数据存储区操作都必须是祖先查询。但是,我没有看到Model.get_or_insert(key_name, **kwds)的文档是如何作为祖先查询。对于以下示例,由于未在最后一行的参数中指定“parent”,因此第二行中的parent=kwds.get('parent')的结果不会是None,因此将查询否定为祖先查询?:

def txn(key_name, **kwds):
    entity = Story.get_by_key_name(key_name, parent=kwds.get('parent')) # parent is not defined?
    if entity is None:
        entity = Story(key_name=key_name, **kwds)
        entity.put()
    return entity

def get_or_insert(key_name, **kwargs):
    return db.run_in_transaction(txn, key_name, **kwargs)

get_or_insert('some key', title="The Three Little Pigs")  # no parent specified

link to documentation

我不是想在这里拆分,我只是无法理解如何在我自己的应用程序中正确使用事务,并且正在查看此文档以增强我的理解。

非常感谢你的帮助!

2 个答案:

答案 0 :(得分:3)

您需要祖先查询来保证涉及多个实体的事务的原子性。事务中的所有实体都需要共享相同的祖先。 Model.get_or_insert()只检索一个实体,它显然与自己共享相同的祖先。

关键路径/祖先确定数据在App Engine数据存储区中的存储方式。具有共同祖先的实体存储在同一个数据库分片上,这样可以更轻松地实现原子事务,而无需在分片之间进行同步。

如果您正在使用HRD(此时您可能正在使用),Cross Group交易也可用,但我不太确定它们在幕后的工作方式。 http://code.google.com/appengine/docs/python/datastore/overview.html#Cross_Group_Transactions

答案 1 :(得分:1)

只要交易中只有一个对象,您就可以传递无祖先 尝试创建/获取多个实体将引发异常。