3

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

4 回答 4

1

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

一种选择是在事务之外执行查询,并将结果传入。不过,看起来您正试图按名称检索分片计数器的特定分片,这应该可以在不使用查询的情况下全部,因为它应该由它的键名来识别。不过,由于我不熟悉 Django 的模型 API,我无法建议您如何在 Django 中执行此操作。

于 2011-04-06T01:40:59.510 回答
1

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

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

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

于 2012-02-15T07:04:15.703 回答
0

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

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

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

但是请注意,您可以在事务中进行的查询受到限制:截至 2011 年 1 月,Django nonrel 不支持实体组,这是导致上述错误的原因。

于 2011-04-19T16:42:38.017 回答
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)
于 2015-02-13T13:26:26.150 回答