• Django之orm


    • orm的定义
    • 为什么要有orm
    • orm的核心在哪
    • 什么时候queryset 被 evaluated (个人理解为利用)
    • 什么时候queryset会被缓存
    • 什么时候缓存被破坏
    • F查询和Q查询
    • 多表查询会出现什么问题以及如何避免
        1.  orm 是object-related-mapping 的缩写,翻译为对象关系映射------>将我们对编写的model模型操作 和对数据库里面的表字段的操作 相关联----->形成一种映射的关系
        2. 第二个问题放到后面作
        3. 核心在于懒加载(个人认为哈) 那么什么是懒加载:the act of creating a 

    QuerySet

        doesn’t involve any database activity.(当我们创建queryset时,并没有查询数据库)
    1.   instances = Model.objects.all()------>并没有连接数据库,没对数据库中的表做任何操作(好处就是显而易见的数据库的负荷减少了)
    2. 文档说明:Internally, a QuerySet can be constructed, filtered, sliced, and generally passed around without actually hitting the database----->当queryset被创建,过滤,切片,传递的时候都没有真正的查询数据库

    • 那queryset被创建,什么时候才会真正连接操作数据库:当querySet被 使用的时候
      1.   步长切片
      2.        len(queruset)
      3.        字符串化queryset 
      4.         列表化queryset:instances = list(queryset)
      5.      ***  遍历queryset
      6.      从queryset中取值
    •  使用queryset无法避免,那么就应该考虑如何减少数据库操作----使用queryset 是能够被缓存的(The first time a QuerySet is evaluated – and, hence, a database query happens – Django saves the query results in the QuerySet’s cache and returns the results that have been explicitly requested (e.g., the next element, if the QuerySet is being iterated over)):
      1.   
        #错误示范
        
        
        >>> print([e.headline for e in Entry.objects.all()])
        >>> print([e.pub_date for e in Entry.objects.all()])
        #这样就会进行两次迭代 两次hitting database
        #正确演绎
        >>> queryset = Entry.objects.all() >>> print([p.headline for p in queryset]) # Evaluate the query set. >>> print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation.
          
    • 那么如何避免queryset的缓存被破坏:
      1.   缓存被破坏的条件: this means that limiting the queryset using an array slice or an index will not populate the cache.(数组切片,和索引取值)
        1.   
          >>> queryset = Entry.objects.all()
          >>> print(queryset[5]) # Queries the database
          >>> print(queryset[5]) # Queries the database again
      2. 如何避免:在需要的时候,先对queryset进行操作,使他们被缓存,然后在缓存的queryset进行操作
        1.   
          >>> queryset = Entry.objects.all()
          >>> [entry for entry in queryset] # Queries the database
          >>> print(queryset[5]) # Uses cache
          >>> print(queryset[5]) # Uses cache
      3.   常见的被缓存的情况:
        1.   
          >>> [entry for entry in queryset]
          >>> bool(queryset)
          >>> entry in queryset
          >>> list(queryset)
      4.   所以 在django restframework中 在GenericApiView层次上 内置了 queryset类属性!
    • F查询和Q查询:
      1.   导入:from django.db.models import F,Q
      2.       F查询:常用来做条件比较   ;*** 在model层次上的操作是直接对数据库表字段的操作(1.避免了竞态条件!!! 2 避免了将模型数据拉倒内存中然后在进行操作)
      3.       Q 查询 :用来做字段查询条件之间的连接符:where ... and(or) ...,起到这种 and(or)作用,但是要注意的是Q查询的时候,关键字字段要在其之后  (Q(),‘look_up’=args)  
    • 多表查询
      1. 第一步优化:
        1. 需要查询两张关联表的时候,正常情况,我们需要查询两次database,第一次找出目标对象,第二次找出目标对象在数据表中关联的对象;
          1.   这种时候 select_related()字段的 会一次性取回两张表
          2. 需要查询多张表的时候,查询4张,这个时候,我们往往查询表的次数会高于4次,因为有一些表作为枢纽表总是会被重复查询
          3.     这时候使用prefetch_related:我们只会4次,然后python程序会帮我们关联4张表中我们需要的数据
        2. 第二步优化:
          1.   结合使用select_related 和prefetch_related 字段 还能减少查询次数!
          2.   有兴趣研究的  https://www.cnblogs.com/evilliu/articles/6109640.html
    • 为什么有orm
      1.   便捷性:将select语句封装为函数操作,更优雅,更简单
      2.     从懒加载和缓存的层次:对于内存利用更为合适

  • 相关阅读:
    window下安装QT出错解决方案
    wiin10下VS2015+opencv3.4.0-extra_modules+CMake配置
    可重入、线程安全辨析与场景举例
    WPF仿网易云音乐系列(三、播放进度条+控制按钮)
    WPF仿网易云音乐系列(二、歌单创建窗口+登录设置模块)
    WPF仿网易云音乐系列(一、左侧菜单栏:Expander+RadioButton)
    WPF仿网易云音乐系列(序)
    C# WPF仿360安全卫士11
    crontab的语法规则格式(每分钟、每小时、每天、每周、每月、每年定时执行 规则)
    Pymysql 连接 Mysql 数据库及增删改查操作
  • 原文地址:https://www.cnblogs.com/zengmu/p/13084832.html
Copyright © 2020-2023  润新知