Django框架之第八篇(模型層補充)--數據庫的查詢與優化:only/defer,select_related與prefetch_related,事務

在設置外鍵字段時須要注意:數據庫

當你使用django2.x的版本時候,在創建外鍵關係時,須要你手動添加幾個關鍵點參數django

models.cascade   #設置級聯刪除
db_constraints

數據庫查詢與優化fetch

only和defer優化

orm內全部的語句操做,都是惰性操做:只會在你真正須要數據的時候纔會走數據庫,若是你單單隻寫orm語句是不會走數據庫的。這樣設計的好處在於減輕數據庫的壓力。atom

res = models.Book.objects.values('title')   #普通查詢方式 獲取到的結果是列表套字典
res1 = models.Book.objects.only('title')   #結果是一個個對象能夠直接點屬性獲取到屬性值 print(res)
print(res1)

 

 only和普通查詢的不一樣就是能直接獲取到對象,除了能夠獲取到上面的title屬性值,還能夠獲取到該對象其餘的屬性值。可是也有優缺點,看下面的例子。spa

res1 = models.Book.objects.only('title')
for r in res1:
       print(r.title)  #只走一次數據庫查詢 print(r.price)  #每取一次數據就走數據庫一次

r.title設計

 

 r.pricecode

 only總結:當你獲取一個不是only括號內指定的字段的時候,不會報錯,而是會頻繁的走數據庫查詢orm

defer與only是相反的對象

res1 = models.Book.objects.defer('title')
    for r in res1:
        print(r.price)  #不是括號內的字段,只走一次數據庫查詢

 

defer總結:defer會將不是括號內的全部的字段信息所有查詢出來封裝到對象中,一旦你點擊了括號內的字段,那麼會頻繁的走數據庫查詢

select_related與prefetch_related

select_related幫你直接連表操做,查詢數據,括號內只能放外鍵字段

res1 = models.Book.objects.select_related('publish')   #鏈接book表和publish表 for r in res1:
        print(r.publish.name)

總結:select_related:會將括號內的外鍵字段所關聯的那張表直接所有拿過來(也能夠一次性拿多張表)跟當前表拼接操做,從而下降你跨表查詢,數據庫的壓力

注意:select_related括號內只能放外鍵字段(一對一和一對多)

res = models.Book.objects.all().select_related('外鍵字段1__外鍵字段2__外鍵字段3__外鍵字段4')

prefetch_related不主動連表

res2 = models.Book.objects.prefetch_related('publish')
for r in res2:
        print(r.publish.name)

不主動連表操做(可是內部給你的感受像是連表操做了)而是將book表中的publish所有拿出來,再取publish表中將id對應的全部的數據取出,括號內有幾個外鍵字段,就會走幾回數據庫查詢操做。

 

 事務

ACID

  原子性、一致性、隔離性、持久性

from django.db import transaction
    
with transaction.atomic():
    """數據庫操做
    在該代碼塊中書寫的操做 同屬於一個事務
    """
    models.Book.objects.create()
    models.Publish.objects.create()
    # 添加書籍和出版社 就是同一個事務 要麼一塊兒成功要麼一塊兒失敗
print('出了 代碼塊 事務就結束')
相關文章
相關標籤/搜索