【问题标题】:How is Model.get_or_insert() an ancestor transaction in app engineModel.get_or_insert() 如何成为应用引擎中的祖先事务
【发布时间】:2012-03-07 15:29:41
【问题描述】:

我不明白用于 python 的 Model.get_or_insert(key_name, **kwds) 方法的谷歌应用引擎是如何工作的。

据我了解,事务中的所有数据存储操作都必须是祖先查询。但是,我看不到 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)

我并不想在这里分心,我只是在理解如何在我自己的应用程序中正确使用事务时遇到了困难,我正在寻找这个文档来加深我的理解。

非常感谢您的帮助!

【问题讨论】:

    标签: python google-app-engine transactions bigtable


    【解决方案1】:

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

    关键路径/祖先决定了数据在 App Engine 数据存储区中的存储方式。具有共同祖先的实体存储在同一个数据库分片上,从而更容易实现原子事务,而无需在分片之间进行同步。

    如果您正在使用 HRD(此时您可能正在使用该 HRD),也可以使用跨组事务,尽管我不太确定它们在幕后是如何工作的。 http://code.google.com/appengine/docs/python/datastore/overview.html#Cross_Group_Transactions

    【讨论】:

    • 将 xg=True 传递给 transaction() 函数。然后您可以在事务回调中最多触及 5 个实体组,而不是仅限于一个。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-03-19
      • 2014-12-22
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多