我有一个这样的Django模型:
class MyModel(models.Model):
upper_limit = models.PositiveIntegerField()
counter = models.PositiveIntegerField()
记录的计数器需要经常递增:
^{pr2}$问题是:我需要确定我的模型计数器小于mymodel.上限在更新之前。我可以在更新前进行查询:
if mymodel.counter < mymodel.upper_limit:
mymodel.counter = F('counter') + 1
mymodel.save()
但这种方法也存在问题:计数器可能不准确。其他线程可能在我的查询后更新了数据库中的计数器,当我增加它时,计数器将超过限制。我知道我可以使用select_for_update()
来锁定行,但我不想这样做,因为那样所有增量操作都将被序列化,从而阻塞线程。在
我只想在一个查询中,仅在计数器小于上限时更新计数器:
UPDATE MyModel set counter = counter + 1
where id=123 and counter<upper_limit
这对Django ORM可行吗?在
我一直在考虑pre_save signal,但是信号处理程序需要知道上限,所以这是一个死胡同。
更新: 这个怎么样,这会生成一个SQL吗?在
updated_rows = MyModel.objects.filter(pk=123,
counter__lt=F("upper_limit")).update(counter=F("counter")+1)
# if updated_rows > 0, I know the counter is incremented
我不确定上面的语句是否能得到单个查询,因为update方法返回一个int,而不是queryset,因此我无法打印它的query
。在
你需要数据库级别的一致性,所以应用程序端的任何一个方法都不能保证这一点。你需要的是数据库内部的逻辑。您可以通过触发器或Django>;=1.8中的conditional updates来实现。在
相关问题 更多 >
编程相关推荐