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

java哥 阅读:36 2025-02-15 21:57:57 评论:0

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

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

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

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

这里有两个问题;

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

这种行为是否与我通过脚本运行有关?如果相同的循环将在 View 中运行。行为会有什么不同吗?

编辑:

我已经通过对类似问题的建议来将 transaction-isolation 更改为 READ-COMMITTED 。这会导致常规 Django View 操作出现性能缺陷吗?

请您参考如下方法:

看来您在这里遇到了竞争条件。如果您看一下 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() 

事实上,上面的代码也可能受到竞争条件的影响,并且创建的对象多于 documentation 中创建的对象。还说:但是,如果在数据库级别没有为 get_or_create 调用中使用的 kwargs 强制执行唯一性(请参阅 unique 或 unique_together),则此方法容易出现竞争条件,这可能导致多行具有相同的同时插入参数。

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

或者,如果该字段不能是唯一的,我建议您尝试使用 transactions明确地。

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


标签:Django
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号