• 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'
    
  • 相关阅读:
    项目开发日志——第三篇
    项目开发日志——第二篇
    项目开发日志——第一篇
    实时控制软件设计第四周作业
    实时控制软件设计第三周作业
    实时控制软件设计第二周作业
    关于开放式CNC系统实时软件控制系统的一些简单分析
    初学者的卡尔曼滤波——扩展卡尔曼滤波(一)
    C++_Eigen函数库用法笔记——The Array class and Coefficient-wise operations
    C++_Eigen函数库用法笔记——Block Operations
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/13841886.html
Copyright © 2020-2023  润新知