zoukankan      html  css  js  c++  java
  • Django ORM Queryset 的缓存机制, 惰性查询简述

    在Django的ORM中 必须注意由于QuerySet的 cache导致的数据获取不正确的问题

    在哪些情况下不会出发QuerySet缓存?
    隐式存储QuerySet(查询语句没有显示赋值给变量而直接进行遍历或截取)

    >>> from project.models import ProjectModel
    >>> 
    >>> print([project_instance.name for project_instance in ProjectModel.objects.all()])
    ['first-test', 'test百度', 'project002']
    >>> ProjectModel.objects.filter(name="project002").update(name="project003")
    1
    >>> print([project_instance.name for project_instance in ProjectModel.objects.all()])
    ['first-test', 'test百度', 'project003']
    
    

    而显示的存储QuerSet 并且经过完整遍历才会触发缓存

    完整遍历的情况

    >>> projects_queryset = ProjectModel.objects.all()
    >>> print([project_instance for project_instance in projects_queryset])        # 完整遍历
    [<ProjectModel: first-test>, <ProjectModel: test百度>, <ProjectModel: project007>]
    >>> ProjectModel.objects.filter(name="project007").update(name="project008")
    1
    >>> projects_queryset[1:3]
    [<ProjectModel: test百度>, <ProjectModel: project007>]  # project007还是缓存的老数据
    

    不遍历的情况

    >>> projects_queryset = ProjectModel.objects.all()
    >>> projects_queryset
    <QuerySet [<ProjectModel: first-test>, <ProjectModel: test百度>, <ProjectModel: project008>]>
    >>> ProjectModel.objects.filter(name="project008").update(name="project009")
    1
    >>> projects_queryset[1:3]
    <QuerySet [<ProjectModel: test百度>, <ProjectModel: project009>]>  # 没拿缓存 project009
    

    还有一种场景 也是需要注意的:
    获取到单个QuerySet对象后 通过objects update方法修改了部分字段值,此时的QuerySet还是缓存数据

    >>> projects_obj = ProjectModel.objects.filter(name="project0011").first()
    >>> projects_obj.name
    'project0011'
    >>> ProjectModel.objects.filter(name="project0011").update(name="project0012")
    1
    >>> projects_obj.name
    'project0011'
    
    

    有两种方法可以解决这个问题

    1. 使用save修改
    >>> projects_obj = ProjectModel.objects.filter(name="project0012").first()
    >>> projects_obj.name
    'project0012'
    >>> projects_obj.name = "project0013"
    >>> projects_obj.save()
    >>> projects_obj.name
    'project0013'
    
    1. 使用refresh_from_db()
    >>> projects_obj = ProjectModel.objects.filter(name="project0013").first()
    >>> projects_obj.name
    'project0013'
    >>> ProjectModel.objects.filter(name="project0013").update(name="project0014")
    1
    >>> projects_obj.refresh_from_db()
    >>> projects_obj.name
    'project0014'
    
  • 相关阅读:
    第十八章 并发登录人数控制——《跟我学Shiro》(http://blog.csdn.net/lhacker/article/details/19334305)
    spring4 hibernate4 transaction
    sqllite
    http://www.cnblogs.com/enshrineZither/p/3793459.html
    MyBatis 显示日志
    Centos7配置更新国内yum源
    解决Centos运行yum 报错:坏的解释器
    用python生成基于lombok 和 hibernate 生成javabean
    数据库事务中的隔离级别和锁+spring Transactional注解
    springmvc 通过异常增强返回给客户端统一格式
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/13841886.html
Copyright © 2011-2022 走看看