在Django AppEngine上使用事务

时间:2011-04-05 13:32:59

标签: google-app-engine transactions djangoappengine

AppEngine文档中有几个事务示例,使用AppEngine本机技术在本机对象上进行事务处理查询。

根据http://www.allbuttonspressed.com/projects/django-nonrel [1]的文档,我想使用AppEngine事务来查询Django对象。这可能吗?

def txn():
    index = random.randint(0, NUM_SHARDS - 1)
    shard_name = "shard" + str(index)
    counter = SimpleCounterShard.objects.filter(name=shard_name)
    # Make counter if it doesn't exist 
    if not len(counter):
        counter = SimpleCounterShard(name=shard_name)
    counter.count += 1
    counter.put()
db.run_in_transaction(txn)

这当前失败,“只允许在事务中进行祖先查询”。我明白这是要求我做一些涉及祖先课程的事情,但我不确定是什么或为什么。

任何提示?

[1]“你不能使用Django的事务API。如果你的特定数据库支持特殊类型的事务(例如,App Engine上的run_in_transaction()),你必须使用特定于平台的函数。”

4 个答案:

答案 0 :(得分:1)

正如错误消息所示,App Engine上的事务中只允许某些类型的查询 - 特别是应用.ancestor()过滤器的事务。诸如您尝试执行的查询之类的查询无法以事务方式执行。

一个选项是在事务外部执行查询,并将结果传入。看起来你试图通过名称检索分片计数器的特定分片,而且应该可以不使用一个查询,因为它应该由其键名识别。既然我不熟悉Django的模型API,我不能建议你如何在Django中这样做。

答案 1 :(得分:1)

Nailer在他的回答中击中头部(对不起双关语):DjangoAE不支持实体组。但是,这个有进取心的开发者djangoappengine分支有非正式的支持。

https://github.com/django-nonrel/djangoappengine/pull/10

补丁尚未完成,但我计划在接下来的几周内试用,并在此处更新。

答案 2 :(得分:0)

AppEngine WebApp Sharded Counter示例的Django端口,包括常规Django对象上的事务,存在于:

https://bitbucket.org/twanschik/sharded-counters-nonrel。查看sharded_counters / models.py,其中包括所讨论的单个读取/递增/写入操作。

具体来说, @commit_locked 装饰器可用于原子地读取/写入/增加Django模型。

但是请注意,您在事务中可以进行的查询受限:Django nonrel, as of Jan 2011, does not support entity groups,这是上述错误的原因。

答案 3 :(得分:0)

可以使用更优雅的方式:

from django.db.models import F
Accumulator.objects.filter(pk=1).update(counter=F('counter') + 5)

https://www.allbuttonspressed.com/blog/django/f-objects-and-queryset-update-support-in-djangoappengine

另一个例子是:https://www.allbuttonspressed.com/blog/django/2010/01/Sharding-with-Django-on-App-Engine#django-s-advantage

YouTubeVideo.objects.filter(pk=keyname).update(
    views_count=F('views_count')+1)
相关问题