Django的。线程安全更新或创建。 [英] Django. Thread safe update or create.

查看:196
本文介绍了Django的。线程安全更新或创建。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道,该更新是线程安全操作。
这意味着,当你这样做:

We know, that update - is thread safe operation. It means, that when you do:

  SomeModel.objects.filter(id=1).update(some_field=100)

而不是:

sm = SomeModel.objects.get(id=1)
sm.some_field=100
sm.save()

您的应用程序是相对线程安全和操作 SomeModel.objects.filter(id = 1).update(some_field = 100)不会重写其他模型字段中的数据。

Your application is relativly thread safe and operation SomeModel.objects.filter(id=1).update(some_field=100) will not rewrite data in other model fields.

我的问题是..如果有任何办法

My question is.. If there any way to do

  SomeModel.objects.filter(id=1).update(some_field=100)

对象如果不存在的话

推荐答案

from django.db import IntegrityError

def update_or_create(model, filter_kwargs, update_kwargs)
    if not model.objects.filter(**filter_kwargs).update(**update_kwargs):
        kwargs = filter_kwargs.copy()
        kwargs.update(update_kwargs)
        try:
            model.objects.create(**kwargs)
        except IntegrityError:
            if not model.objects.filter(**filter_kwargs).update(**update_kwargs):
                raise  # re-raise IntegrityError

我想,问题中提供的代码不是非常示范:谁想要设置id为模型?
假设我们需要这个,我们有同步操作:

I think, code provided in the question is not very demonstrative: who want to set id for model? Lets assume we need this, and we have simultaneous operations:

def thread1():
    update_or_create(SomeModel, {'some_unique_field':1}, {'some_field': 1})

def thread2():
    update_or_create(SomeModel, {'some_unique_field':1}, {'some_field': 2})

使用 update_or_create 功能,取决于哪个线程首先,对象将被创建和更新,也不例外。这将是线程安全的,但显然很少使用:取决于竞争条件值 SomeModek.objects.get(some__unique_field = 1).some_field 可以是1或2。

With update_or_create function, depends on which thread comes first, object will be created and updated with no exception. This will be thread-safe, but obviously has little use: depends on race condition value of SomeModek.objects.get(some__unique_field=1).some_field could be 1 or 2.

Django提供F对象,所以我们可以升级我们的代码:

Django provides F objects, so we can upgrade our code:

from django.db.models import F

def thread1():
    update_or_create(SomeModel, 
                     {'some_unique_field':1}, 
                     {'some_field': F('some_field') + 1})

def thread2():
    update_or_create(SomeModel, 
                     {'some_unique_field':1},
                     {'some_field': F('some_field') + 2})

这篇关于Django的。线程安全更新或创建。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆