0

将问题简化为本质,我想在 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 本地完成吗?

4

1 回答 1

0

我想我有自己的解决方案......这基本上锁定了表中的所有行,直到事务提交。(这不是很理想)

# 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 替换。

于 2013-03-27T17:15:17.963 回答