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()),你必须使用特定于平台的函数。”
答案 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)
YouTubeVideo.objects.filter(pk=keyname).update(
views_count=F('views_count')+1)