将问题简化为本质,我想在 django 中本地执行此操作,而不是嵌入 sql:
UPDATE job SET state_id = 100
WHERE job.id = 1 and 0 in (select count(*) from job where state_id = 100);
当且仅当当前状态 100 中有 0 个作业时,此 SQL 语句将自动将状态更新为 100。
本质上,我只希望一份工作处于 100 州。
这可以在 django 本地完成吗?
将问题简化为本质,我想在 django 中本地执行此操作,而不是嵌入 sql:
UPDATE job SET state_id = 100
WHERE job.id = 1 and 0 in (select count(*) from job where state_id = 100);
当且仅当当前状态 100 中有 0 个作业时,此 SQL 语句将自动将状态更新为 100。
本质上,我只希望一份工作处于 100 州。
这可以在 django 本地完成吗?
我想我有自己的解决方案......这基本上锁定了表中的所有行,直到事务提交。(这不是很理想)
# X is the job id to uniquely put into state 100.
with transaction.commit_on_success()
count = 0
myjob = None
for job in Job.objects.select_for_update().all():
if job.state_id == 100:
count +=1
if job.id == X:
myjob = job
if count == 0 and myjob:
myjob.state_id = 100
myjob.save()
或者,您还可以创建一个锁定表来跟踪哪个作业处于唯一状态,
class StateLock(Model):
# XXX: could add an expiration column, too.
state = ForeignKey(State)
locker = ForeignKey(Job, null=True) # Use IntegerField until
# django bug 16715 is fixed!!
并使用
# lock:
StateLock.objects.filter(state=100, locker=None).update(locker=job.id)
# unlock:
StateLock.objects.filter(state=100, locker=job.id).update(locker=None)
注意:在 django 错误 16715 修复之前,可空外键被破坏。否则生成的查询不正确。用 PositiveIntegerField 替换。