主頁 > 軟體設計 > 正反向查詢進階操作、聚合查詢、分組查詢、F與Q查詢、ORM查詢優化

正反向查詢進階操作、聚合查詢、分組查詢、F與Q查詢、ORM查詢優化

2022-09-07 08:44:14 軟體設計

目錄
  • 正反向查詢進階操作
  • 聚合查詢
    • 1.使用聚合函式之前需要匯入模塊
    • 2.聚合函式的使用
    • 3.關鍵字aggregate
  • 分組查詢
    • 1.分組查詢
    • 2.回傳值
    • 3.分組查詢關鍵字
  • 分組練習題
  • F與Q查詢
    • F查詢
    • Q查詢
      • Q查詢的進階用法
  • ORM查詢優化
    • 1.ORM查詢優化之only(單表)
    • 2.ORM查詢優化之defer(單表)
    • 3.ORM查詢優化之select_related(多表)
    • 4.ORM查詢優化之prefetch_related(多表)
  • 額外補充個知識:當表中已經有資料的情況下 添加新的欄位需要指定一些引數
  • 報錯問題

正反向查詢進階操作

    '''正反向查詢進階操作'''
    # 1.查詢主鍵為1的書籍對應的出版社名稱及書名
    res = models.Publish.objects.filter(book__pk=1).values('name', 'book__title')
    print(res)  # <QuerySet [{'name': '清華大學出版社', 'book__title': '女人你成功引起了我的注意'}]>

    # 2.查詢主鍵為3的書籍對應的作者姓名及書名
    res1 = models.Author.objects.filter(book__pk=3).values('name', 'book__title')
    print(res1)  # <QuerySet [{'name': 'jfw', 'book__title': '涼生,我們可不可以不憂傷'}]>

    # 3.查詢zxb的作者的電話號碼和地址
    res2 = models.AuthorDetail.objects.filter(author__name='zxb').values('phone', 'addr')
    print(res2)  # <QuerySet [{'phone': 119, 'addr': '浙江'}]>

    # 4.查詢東方出版社出版的書籍名稱和價格
    res4 = models.Book.objects.filter(publish__name='東方出版社').values('title', 'price')
    print(res4)  # <QuerySet [{'title': '桃疆', 'price': Decimal('14.67')}, {'title': '三生三十十里桃花', 'price': Decimal('35.98')}, {'title': '玄霜', 'price': Decimal('54.21')}]>

    # 5.查詢zxr寫過的書的名稱和日期
    res5 = models.Book.objects.filter(author__name='zxb').values('title', 'publish_time')
    print(res5)  # <QuerySet [{'title': '女人你成功引起了我的注意', 'publish_time': datetime.datetime(2022, 9, 5, 13, 16, 43, 303992, tzinfo=<UTC>)}]>

    # 6.查詢電話是110的作者姓名和年齡
    res6 = models.Author.objects.filter(author_detail__phone=110).values('name', 'age')
    print(res6)  # <QuerySet [{'name': 'zxr', 'age': 18}]>

    # 7.查詢主鍵為1的書籍對應的作者電話號碼
    res7 = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
    print(res7)  # <QuerySet [{'phone': 120}, {'phone': 119}]>
    res8 = models.Author.objects.filter(book__pk=1).values('author_detail__phone')
    print(res8)  # <QuerySet [{'author_detail__phone': 120}, {'author_detail__phone': 119}]>

聚合查詢

聚合函式:max、min、sum、avg、count

1.使用聚合函式之前需要匯入模塊

from django.db.models import Max, Min, Sum, Avg, Count

2.聚合函式的使用

聚合函式通常情況下是配合分組一起使用的

3.關鍵字aggregate

沒有分組之前如果單純的使用聚合函式 需要關鍵字aggregate

# 1.查詢所有書的平均價格
res = models.Book.objects.aggregate(Avg('price'))
print(res)  # {'price__avg': Decimal('183.117778')}

image

res1 = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Avg('price'), Count('pk'))
print(res1)

image

分組查詢

image
報錯原因
image

打開MySQL
輸入>>>:show variables like '%mode%';

分組有一個特性 默認只能夠直接獲取分組的欄位 其他欄位需要使用方法
我們也可以忽略掉該特性 將sql_mode中only_full_group_by配置移除即可
# 示例1:統計每一本書的作者個數
res = models.Book.objects.annotate(author_num=Count('author__pk')).values('title', 'author_num')
print(res)

"""
    1.按照整條資料分組
        models.Book.objects.annotate()  按照一條條書籍記錄分組
    2.按照表中某個欄位分組()
        models.Book.objects.values('title').annotate()  按照annotate之前values括號中指定的欄位分組
"""

"""
<QuerySet [{'title': '女人你成功引起了我的注意爆款~爆款', 'author_num': 2},
{'title': '涼生,我們可不可以不憂傷爆款~爆款', 'author_num': 1},
{'title': '桃疆爆款~爆款', 'author_num': 2},
{'title': '我是你的,生生世世爆款~爆款', 'author_num': 2},
{'title': '國民大偵探爆款~爆款', 'author_num': 1},
{'title': '十宗罪爆款~爆款', 'author_num': 1},
{'title': '三生三十十里桃花爆款~爆款', 'author_num': 1},
{'title': '玄霜爆款~爆款', 'author_num': 1},
{'title': '一生一世爆款~爆款', 'author_num': 1}]>
"""

1.分組查詢

annotate()為呼叫的QuerySet中每一個物件都生成一個獨立的統計值(統計方法用聚合函式,所有使用前要從django.db.models引入Avg,Max,Count,Sum(首字母大寫)),

2.回傳值

分組后,用values取值,則回傳值是QuerySet書籍型別里面為一個個字典
分組后,用values_list取值,則回傳值是QuerySet資料型別里面為一個個元組

MySQL中的limit相當于ORM中的QuerySet資料型別的切片,

3.分組查詢關鍵字

annotate()  里面放聚合函式

1.values 或者 values_list 放在 annotate 前面:values 或者 values_list 是宣告以什么欄位分組,annotate 執行分組,
2.values 或者 values_list 放在annotate后面: annotate 表示直接以當前表的pk執行分組,values 或者 values_list 表示查詢哪些欄位, 并且要將 annotate 里的聚合函式起別名,在 values 或者 values_list 里寫其別名,
3.filter放在 annotate 前面:表示where條件
4.filter放在annotate后面:表示having

跨表分組查詢本質就是將關聯表join成一張表,再按單表的思路進行分組查詢

分組練習題

models后面點什么 就按什么分組 

author_num 是我們自己定義的欄位 用來存盤統計出來的每本書對應的作者個數

1.統計每一本書的作者個數

res = models.Book.objects.annotate(author_num=Count('author__pk')).values('title', 'author_num')
print(res)
res1 = models.Book.objects.values('publish_id').annotate(book_num=Count('pk')).values('publish_id','book_num')
print(res1)
"""
    1.按照整條資料分組
        models.Book.objects.annotate()  按照一條條書籍記錄分組
    2.按照表中某個欄位分組()
        models.Book.objects.values('title').annotate()  按照annotate之前values括號中指定的欄位分組
"""
"""
<QuerySet [{'title': '女人你成功引起了我的注意', 'author_num': 2},
{'title': '涼生,我們可不可以不憂傷', 'author_num': 1},
{'title': '桃疆', 'author_num': 2},
{'title': '我是你的,生生世世', 'author_num': 2},
{'title': '國民大偵探', 'author_num': 1},
{'title': '十宗罪', 'author_num': 1},
{'title': '三生三十十里桃花', 'author_num': 1},
{'title': '玄霜', 'author_num': 1},
{'title': '一生一世', 'author_num': 1}]>
"""

image

2.統計每個出版社賣的最便宜的書的價格

res1 = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
print(res1)
"""
<QuerySet [{'name': '清華大學出版社',
'min_price': Decimal('28.98')},
{'name': '北方出版社', 'min_price': Decimal('34.98')},
{'name': '南方出版社', 'min_price': Decimal('56.29')},
{'name': '東方出版社', 'min_price': Decimal('14.67')}]>
"""

image
3.統計不止一個作者的圖書

'''filter在annotate前面則是where 在annotate后面則是having'''
res = models.Book.objects.annotate(author_num=Count('author__pk')).filter(author_num__gt=1).values('title', 'author_num')
print(res)

image
4.查詢各個作者出的書的總價格

res = models.Author.objects.annotate(book_sum_price=Sum('book__price')).values('name', 'book_sum_price')
print(res)

"""
<QuerySet [{'name': 'zxr', 'book_sum_price': Decimal('159.25')},
{'name': 'wyn', 'book_sum_price': Decimal('1365.63')},
{'name': 'zxb', 'book_sum_price': Decimal('1383.86')},
{'name': 'jfw', 'book_sum_price': Decimal('103.95')}]>
"""

image

F與Q查詢

F查詢

能夠幫助你直接獲取到串列中某個欄位對應的資料

注意:
在操作字串型別的資料的時候, F不能夠直接做到字串的拼接

1.查詢賣出書大于庫存數的書籍

res = models.Book.objects.filter(storage_num__gt=F('sale_num'))
print(res)

image
將所有書籍的價格上漲1000快

res = models.Book.objects.update(price=F('price') + 1000)

image
image
給所有書籍名稱后面加上爆款后綴
針對字串資料無法直接拼接
image

models.Book.objects.filter().all().update(title=F('title') + '爆款')  # 針對字串資料無法直接拼接
    # 匯入Concat模塊
    from django.db.models.functions import Concat
    # 匯入Value模塊
    from django.db.models import Value
    models.Book.objects.filter().all().update(title=Concat(F('title'), Value('~爆款')))

image

Q查詢

可以改變filter括號內多個條件之間的邏輯運算子,還可以將查詢的結果改為字串形式

filter()等方法中的關鍵字引數查詢都是一起進行"and",如果你需要執行更復雜的查詢(列如ORM陳述句),你可以使用Q物件,

查詢賣出數大于100并且價格小于60的書籍

res = models.Book.objects.filter(Q(sale_num__gt=100), Q(price__lt=600))
print(res)

image

查詢賣出數大于130或者價格小于30的書籍

res = models.Book.objects.filter(Q(sale_num__gt=130) | Q(price__lt=30))
print(res)

image

查詢賣出數不是大于80或者價格大于600的書籍

res = models.Book.objects.filter(~Q(sale_num__gt=80) | Q(price__gt=600))
print(res)

image
總結

,               and關系
|               or關系
~               not關系

Q 默認是and,可以進行修改
    q = Q()
    q.connector = 'or'

Q查詢的進階用法

可以將查詢的結果改為字串形式

先產生一個物件
    q = Q()
修改默認的物件
    q.connector = 'or'
添加查詢條件,第一個寫一個字串的欄位名 第二個元素寫一些具體的數值
    q.children.append(('pk', 1))
    q.children.append(('publish_id', 3))
添加好以后q物件支持直接用filter進行篩選
    res = models.Book.objects.filter(q)
    print(res)

image

image

ORM查詢優化

django orm默認都是惰性查詢
    當orm的陳述句在后續的代碼中真正需要使用的時候才會執行
django orm自帶limit分頁
    減輕資料庫端以及服務端的壓力

1.ORM查詢優化之only(單表)

res = models.Book.objects.only('title','price')
for obj in res:
     print(obj.title)
     print(obj.price)
     print(obj.publish_time)
    """
    only會將括號內填寫的欄位封裝成一個個資料物件 物件在點擊的時候不會再走資料庫查詢
    但是物件也可以點擊括號內沒有的欄位 只不過每次都會走資料庫查詢 
    如果看到有人只有only查詢的話 盡量不要去點括號內沒有的欄位 因為它每次都會去查詢一次
    """

image
image

2.ORM查詢優化之defer(單表)

res = models.Book.objects.defer('title', 'price')
for obj in res:
    # print(obj.title)
    # print(obj.price)
    print(obj.publish_time)
    """
    defer與only剛好相反
        資料物件點擊括號內出現的欄位 每次都會走資料庫查詢
        資料物件點擊括號內沒有的字典 不會走資料庫查詢
    """

image

3.ORM查詢優化之select_related(多表)

res = models.Book.objects.all()
for obj in res:
     print(obj.publish.name)  # 頻繁走資料庫查詢

res = models.Book.objects.select_related('publish')
"""
    select_related括號內只能接收外鍵欄位(一對多 一對一) 它會在內部自動拼表 得出的資料物件在點擊表中資料的時候都不會再走資料庫查詢
"""

image
image

4.ORM查詢優化之prefetch_related(多表)

for obj in res:
     print(obj.publish.name)
"""
    prefetch_related底層其實是子查詢 將查詢之后的結果也一次性封裝到資料物件中 用戶在使用的時候是感覺不出來的
"""
res = models.Book.objects.prefetch_related('publish')
for obj in res:
    print(obj.publish.name)

image

額外補充個知識:當表中已經有資料的情況下 添加新的欄位需要指定一些引數

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateTimeField(auto_now=True)

    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    author = models.ManyToManyField(to='Author')
    '''
    當表中已經有資料的情況下 添加新的欄位需要指定一些引數
        1.設定欄位值存于為空    null=True
        2.設定欄位默認值    default=1000
        3.在終端直接給出默認值
    '''
    storage_num = models.IntegerField(verbose_name='庫存數', null=True)
    sale_num = models.IntegerField(verbose_name='賣出數目', default=1000)

    def __str__(self):
        return f'物件:{self.title}'

報錯問題

django.db.utils.OperationalError: (2002, "Can't connect to server on '127.0.0.1' (10061)")
image
解決方法:查看資料庫是否啟動,導致這個錯誤很可能是MySQL停止了服務

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/505350.html

標籤:架構設計

上一篇:為什么GitHub作業流徽章不呈現在JekyllGitHub頁面上?

下一篇:Git不在wsl上作業,但它在沒有pat令牌的情況下在powershell上作業

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more