日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python---django中orm的使用(5)数据库的基本操作(性能相关:select_related,和prefetch_related重点)(以及事务操作)...

發(fā)布時間:2025/7/14 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python---django中orm的使用(5)数据库的基本操作(性能相关:select_related,和prefetch_related重点)(以及事务操作)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
################################################################## # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET # 公共方法:通過操作屬性,來返回一個新的queryset查詢集 ##################################################################
def all(self)# 獲取所有的數據對象def filter(self,
*args, **kwargs)# 條件查詢# 條件可以是:參數,字典,Qdef exclude(self, *args, **kwargs) #排除# 條件查詢# 條件可以是:參數,字典,Q

?

class UserType(models.Model):title = models.CharField(max_length=32)class Person(models.Model):user = models.CharField(max_length=32)ut = models.ForeignKey(to='UserType') 測試用數據庫設計

?

性能相關:select_related,和prefetch_related

select_related:表之間進行join連表操作,一次性獲取關聯的數據。

普通方法獲取數據:

   persion_list = models.Person.objects.all()for item in persion_list:#是已經從person表中獲取的數據print(item.id,item.ut_id,item.user)#需要再次從usertype中再去查詢一次,又發(fā)了一次請求,執(zhí)行的次數增加了,降低了數據庫性能print(item.ut.title) 使用select_related獲取數據:
persion_list = models.Person.objects.all() #一次性獲取到所有數據(數據量大,占內存,只有需要連表時,才會去使用),
   #包含連表(select_related中,可以一次添加多個)的信息 select_related('','',...)persion_list
= models.Person.objects.all().select_related('ut')#select * from person left join usertype where person.ut_id = usertype.id  

for item in persion_list:#是已經從person表中獲取的數據print(item.id,item.ut_id,item.user)#不會再去數據庫中查詢,因為數據已經取出來放在內存中print(item.ut.title)

但是連表查詢也會消耗一部分時間(連表查詢性能低),在某些情況下,使用空間換取時間沒來獲得較小的查詢時間。將連表放在同一張表中.

prefetch_related:多表連表操作時速度會慢,使用其執(zhí)行多次SQL查詢在Python代碼中實現連表操作。分別在多個表中查詢得到結果,然后重組。

使用prefetch_related獲取數據:persion_list = models.Person.objects.all()#一次性獲取到所有數據(數據量大,占內存,只有需要連表時,才會去使用),#prefetch_related('','',...)persion_list = models.Person.objects.all().prefetch_related('ut')#相當于先去person表中select * from person ...(條件)
  #然后再去關聯表中取數據:select * from usertype where id in [persion_list中的id列表],
  #Django將兩者數據數據相結合,然后返回給用戶,
  #此方法不使用連表,也是一次獲取所有數據,高效
for item in persion_list:#是已經從person表中獲取的數據print(item.id,item.ut_id,item.user)#不會再去數據庫中查詢,因為數據已經取出來放在內存中print(item.ut.title)

?

?

聚合查詢:annotate(分組查詢group by)請看:python---django中orm的使用(2)

去重函數:distinct

models.Persion.objects.all().distinct('name') #查詢姓名不重復的人

排序函數:order_by,可以設置多個值,排序先到后

persion_list = models.Person.objects.all().order_by('ut_id','-id') #-id代表id降序排序,默認升序排列

倒序函數:reverse將獲取的數據集翻轉倒序

persion_list = models.Person.objects.all().order_by('ut_id','-id').reverse()

獲取單獨字段:only和排除某些字段defer

only:
persion_list = models.Person.objects.only('id','user') #select id,user from persion 只去獲取這兩個字段值。注意:但是如果在后面獲取數據的時候,獲取其他值(不包含在id,user字段),也可以獲取到,只是會再次去執(zhí)行SQL語句for item in persion_list:print(item.ut_id,item.id,item.user)#其中item.ut_id不在我們only字段中,所以會再次執(zhí)行SQL語句去獲取數據
  #SELECT "app02_person"."id", "app02_person"."ut_id" FROM "app02_person" WHERE "app02_person"."id" = ?; args=(item.id,)
defer:
persion_list = models.Person.objects.defer('ut_id') #效果一致同上面only

切換使用的數據庫using:參數為使用的別名?def using(self, alias):

默認操作下會有models.Person.object.all().using("default') #在setting中設置 settings文件
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),},   'default1': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite4'),},   'default2': {
    'ENGINE': 'django.db.backends.mysql', #數據庫引擎設置
    'NAME': 'test', #數據庫名稱
    'USER': 'root', #數據庫用戶名
    'PASSWORD':'root', #數據庫密碼
    'HOST':'', #主機地址,默認localhost
    'PORT':'3306' #數據庫端口
  }
}

使用方式:

models.Person.object.all().using("default1') 使用第2種數據庫去取數據 models.Person.object.all().using("default2') 使用第3種數據庫引擎下數據庫去取數據

額外的查詢:extra:構造額外的查詢條件或者映射

子查詢:
#persion_list = models.Person.objects.extra(select={'new_tag':'select title from app02_usertype where id= %s'},select_params=(1,))#無法實現動態(tài)#SELECT (select title from app02_usertype where id= 1) AS "new_tag", "app02_person"."id", "app02_person"."user", "app02_person"."ut_id" FROM "app02_person"; args=(1,) 條件查詢:persion_list = models.Person.objects.extra(tables=['app02_usertype'],where=['app02_person.ut_id = app02_usertype.id'])#SELECT "app02_person"."id", "app02_person"."user", "app02_person"."ut_id" FROM "app02_person" , "app02_usertype" WHERE (app02_person.ut_id = app02_usertype.id); args=()

?

################################################## # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS # 公共方法返回一個查詢子集 ##################################################

def values(self, *fields):# 獲取每行數據為字典格式def values_list(self, *fields, **kwargs):# 獲取每行數據為元組def dates(self, field_name, kind, order='ASC'):# 根據時間進行某一部分進行去重查找并截取指定內容# kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)# order只能是:"ASC" "DESC"# 并獲取轉換后的時間- year : 年-01-01- month: 年-月-01- day : 年-月-日models.DatePlus.objects.dates('ctime','day','DESC')def datetimes(self, field_name, kind, order='ASC', tzinfo=None):# 根據時間進行某一部分進行去重查找并截取指定內容,將時間轉換為指定時區(qū)時間# kind只能是 "year", "month", "day", "hour", "minute", "second"# order只能是:"ASC" "DESC"# tzinfo時區(qū)對象models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))""" pip3 install pytzimport pytzpytz.all_timezonespytz.timezone(‘Asia/Shanghai’)""" def none(self):# 空QuerySet對象

raw:執(zhí)行原生SQL:

import pymysql#創(chuàng)建連接 conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='root',db='test',charset="utf8") #創(chuàng)建游標 cursor = conn.cursor()effect_row = cursor.execute("insert into info (name,age,sex) values ('ls',33,'男')")conn.commit()cursor.close()conn.close() pymysql操作數據庫 import pymysqlconn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="root",db="prct",charset="utf8")cursor = conn.cursor(pymysql.cursors.DictCursor) #執(zhí)行存儲過程 cursor.callproc('p1')ret = cursor.fetchall()conn.commit() cursor.close() conn.close()print(ret) pymysql操作數據庫2 ?存儲過程http://www.cnblogs.com/ssyfj/p/8545601.html from django.db import connection,connectionscursor = connections['default'].cursor()cursor.execute("select * from app01_user where id > %s",[1])#select * from app01_user where id > 1; args=[1]row = cursor.fetchall()print(row) #[(2, u'\u674e\u56db'), (3, u'\u738b\u4e94')] Django執(zhí)行原生SQL 執(zhí)行原生SQL:res = models.Person.objects.raw('select * from app02_person')for item in res:print(item) #Person objectres = models.Person.objects.raw('select * from app01_user') #注意是可以去獲取其他數據表的結果集,最好不要這樣做,自己對應自己,不要亂用,易混淆#select * from app01_user; args=()#而且需要為這些聯合表中重復字段設置別名,以免重復select id as nid,username from app01_user   for item in res:print(item) #Person object 設置參數: models.Person.objects.raw('select id as nid,username from app01_user where nid >%s',params=[4,]) 轉換列名: name_map = {'username': 'un', }res = models.Person.objects.raw('select id as nid,username from app01_user', translations=name_map)
指定數據庫 models.Person.objects.raw('select * from app02_person', using="default")

?

?

#################################### # METHODS THAT DO DATABASE QUERIES # 進行數據庫查詢的方法 ####################################
def count(self):# 獲取個數def
get(self, *args, **kwargs):# 獲取單個對象def create(self, **kwargs): # 創(chuàng)建對象

def first(self):# 獲取第一個def last(self):# 獲取最后一個

def delete(self):# 刪除def update(self, **kwargs):# 更新
def set(self,**kwargs):
  #更新,將原來數據清除,重新設置為現在的數據(一對多,多對多)
def exists(self):# 是否有結果 ? 聚合函數:aggregatepython---django中orm的使用(2) # 聚合函數,獲取字典類型聚合結果from django.db.models import Count, Avg, Max, Min, Sumresult = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))===> {'k': 3, 'n': 4} aggregate get_or_create:存在則獲取,不存在則創(chuàng)建并返回該記錄obj, created = models.Person.objects.get_or_create(user='root1',defaults={'ut_id': '1',})
  # defaults 指定創(chuàng)建時,其他字段的值
  # 創(chuàng)建執(zhí)行:INSERT INTO "app02_person" ("user", "ut_id") VALUES ('root1', 1); args=[u'root1', 1]
  # 查詢執(zhí)行:SELECT "app02_person"."id", "app02_person"."user", "app02_person"."ut_id" FROM "app02_person" WHERE "app02_person"."user" = 'root1'; args=(u'root1',) print(obj) #對應的記錄(已有,則是原來的記錄,原來沒有,則是剛剛創(chuàng)建的數據記錄)print(created) #若是剛剛創(chuàng)建則為True,否則為False update_or_create:如果存在,則更新,否則創(chuàng)建obj, created = models.Person.objects.update_or_create(user='root1',defaults={'ut_id': '2',})#BEGIN; args=None#SELECT "app02_person"."id", "app02_person"."user", "app02_person"."ut_id" FROM "app02_person" WHERE "app02_person"."user" = 'root1'; args=(u'root1',)#UPDATE "app02_person" SET "user" = 'root1', "ut_id" = 2 WHERE "app02_person"."id" = 5; args=(u'root1', 2, 5)

?set補充:上面數據庫是基于外鍵一對多,一個人的類型只能有一個,一個類型可以有多個人

下面進行多對多表修改:

class Tag(models.Model):title = models.CharField(max_length=32)class User(models.Model):user = models.CharField(max_length=32)ut = models.ManyToManyField(to='Tag') User對應Tag(多對多)

其中測試set:

obj2 = models.User.objects.filter(id=1).first()obj2.ut.set(2,3)#若是原來是1,2則會被修改為2,3

?

?

也可以用外鍵進行測試需要使用外鍵方來進行修改,否則一些方法無法找到:

obj2 = models.Person.objects.filter(id__gt=2)obj1.ut.all()#錯誤,沒有該屬性,person是多,對應只有一,是一個單獨的對象
  #obj1.ut.all() #AttributeError at /test2 'UserType' object has no attribute 'all'
  print(type(obj1))
  #<class 'app02.models.Person'>
   obj2
= models.UserType.objects.filter(id=1).first()print(obj2.person_set.all())#正確,usertype是一,對應多,獲取的數據是一個數據集,queryset
   # print(type(obj2))  
   #<QuerySet [<Person: Person object>, <Person: Person object>, <Person: Person object>, <Person: Person object>,<Person: Person object>]>, <class 'app02.models.UserType'>) ?

?

ORM的事務操作

一:導入模塊

from django.db import transaction

二:簡單使用

try:with transaction.atomic():表的增刪改操作except Exception as e:return HttpResponse("出現錯誤....")return HttpResponse("ok")

?

轉載于:https://www.cnblogs.com/ssyfj/p/8698865.html

總結

以上是生活随笔為你收集整理的python---django中orm的使用(5)数据库的基本操作(性能相关:select_related,和prefetch_related重点)(以及事务操作)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品人妻一区二区三区免费 | 免费观看一区二区 | 香蕉污视频 | 日本人妖在线 | 秘密基地免费观看完整版中文 | 欧洲亚洲一区二区三区 | 国产乱子伦农村叉叉叉 | 日本黄色高清 | 羞羞的网站在线观看 | 91不卡在线 | 女同久久另类69精品国产 | 国产偷自拍 | 色综合视频 | 波多野结衣中文字幕一区二区 | 国产精品久久久久91 | 男男上床视频 | 久久天堂电影 | 成年人三级视频 | 国产一级片网站 | 色激情综合 | 少妇太紧太爽又黄又硬又爽 | 日韩成人一级片 | 亚洲a黄| 亚洲天堂网在线视频 | 成人资源站 | 中文字幕成人网 | 国产毛片一区 | 色天天干 | 欧美日韩一 | 色诱av手机版 | 欧美三级午夜理伦三级老人 | 一个人在线观看免费视频www | 国产国拍精品亚洲 | 97一区二区三区 | 免费看成人 | 欧美深性狂猛ⅹxxx深喉 | 日韩欧美成人一区 | 成人免费直播 | 国内精品偷拍 | 轮乱| 欧美亚洲国产一区二区三区 | 69sex久久精品国产麻豆 | 四虎一国产精品一区二区影院 | 国产欧美日韩久久 | 国产特黄大片aaaa毛片 | 精品98| 天堂伊人网 | 十八禁毛片 | 尤物国产在线 | 久久久免费 | 夜夜夜操操操 | 在线观看av中文字幕 | 五月天婷婷色 | 99cao| 成人动漫在线免费观看 | 美女毛片在线观看 | 青草视频在线免费观看 | 国产日韩精品一区二区三区在线 | 欧美视频一区在线 | 激情偷乱人成视频在线观看 | 久久在线| 欧美一区免费 | 欧美亚洲另类小说 | 麻豆精品视频 | 色婷婷免费视频 | 免费看三级黄色片 | 找国产毛片看 | 国产色呦呦 | 欧美三级特黄 | 色七七在线 | 欧美午夜影院 | 亚洲一区色 | 亚洲伦理在线视频 | 日本伦理一区 | 大尺度av | 午夜视频www | 无码一区二区三区 | 国产女人18毛片水18精 | 69日影院 | 少妇太爽了 | 日韩亚洲欧美一区 | 日本久久久久久久久 | 在线播放一级片 | 日批视频在线播放 | 成人亚洲网站 | 成人免费xxxxxx视频 | 蜜桃av免费看 | 超碰免费观看 | 欧美日韩成人在线观看 | 神马午夜影院 | 黄色网址免费 | 亚洲熟妇无码一区二区三区导航 | 日本一区二区三区成人 | 欧美性猛交久久久乱大交小说 | 少妇被黑人到高潮喷出白浆 | 亚洲成av人片在线观看无 | 精品人妻少妇一区二区 | 色呦呦视频在线观看 | 六月色婷婷 |