django是否在查询之间缓存模型数据



我使用的是django 1.6,mysql 5.6作为带有innodb表的数据库。调试在我的设置文件中设置为false。

在一个脚本中,我循环遍历一个元素列表,检查它是否已经存在于db中,如果它不存在,则创建,如下所示:

for item in list:
    try:
        MyModel.objects.get(field=item)
    except MyModel.DoesNotExist:
        MyModel.objects.create(field=item)

我希望这只会在数据库中创建一个不存在的项,但这种方法会创建多个具有相同字段值的项。这里似乎正在进行某种缓存。

我有两个问题;

如何更改此行为,以便在每次循环运行中从数据库的最新状态检查是否存在?

此行为是否与我通过脚本运行此操作有关?如果在一个视图中运行相同的循环。行为会有什么不同吗?

编辑:

对于类似的问题,我提出了将事务隔离更改为READ-COMMITTED的建议。这会导致常规Django视图操作的性能缺陷吗?

您在这里似乎遇到了竞争条件。如果你看一下Django为你提供的get_or_create的代码,它看起来与你的相似

try:
   obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
   obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()

事实上,上面的代码也可能受到竞争条件的限制,并创建比文档中所说的However, if uniqueness is not enforced at the database level for the kwargs used in a get_or_create call (see unique or unique_together), this method is prone to a race-condition which can result in multiple rows with the same parameters being inserted simultaneously. 更多的对象

因此,在这种情况下,您的解决方案是使field唯一。

或者,如果字段不能是唯一的,我建议您尝试显式使用事务。

from django.db import transaction 
with transaction.atomic():
    # do_database_stuff

使字段成为唯一

#your model
class MyModel(models.Model):
      field = modesl.IntegerField(unique=True)
      def __unicode__(self):
          return '%s' % self.field

"""your code to interac with the model (Don't matther where you have this code 
(in the view, or elsewhere)), the behavior of the code is going to be the same. 
views.py just is a python file."""
from you_app.models import MyModel
from django.db import IntegrityError
def insert_item(list_item):
    for item in list_item:
        try:
            itemobj = MyModel.objects.create(field=item)
        except IntegrityError:
            #exists, posible you want to make some update here
            itemobj = MyModel.objects.get(field=item)
            #maybe update...
        else:
            #do whatevert you want with itemobj
            print itemobj

最新更新