我们知道,该更新 - 是线程安全的操作.这意味着,当你这样做时:
SomeModel.objects.filter(id=1).update(some_field=100)
Run Code Online (Sandbox Code Playgroud)
代替:
sm = SomeModel.objects.get(id=1)
sm.some_field=100
sm.save()
Run Code Online (Sandbox Code Playgroud)
您的应用程序是相对线程安全的,操作SomeModel.objects.filter(id=1).update(some_field=100)
不会重写其他模型字段中的数据.
我的问题是..如果有任何办法可以做
SomeModel.objects.filter(id=1).update(some_field=100)
Run Code Online (Sandbox Code Playgroud)
但是如果不存在对象的创建?
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
Run Code Online (Sandbox Code Playgroud)
我认为,问题中提供的代码不是很有说服力:谁想为模型设置id?让我们假设我们需要这个,我们有同步操作:
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})
Run Code Online (Sandbox Code Playgroud)
使用update_or_create
函数,取决于哪个线程首先出现,对象将被创建和更新,没有异常.这将是线程安全的,但显然没什么用处:取决于竞争条件值SomeModek.objects.get(some__unique_field=1).some_field
可能是1或2.
Django提供了F对象,因此我们可以升级代码:
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})
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8302 次 |
最近记录: |