今日内容概要

  • 1 > 聚合查询
  • 2 > 分组查询
  • 3 > F与Q查询
    • 3.1 > F查询
    • 3.2 > Q查询
  • 4 > ORM查询优化
    • 4.1 > only与defer
    • 4.2 > select_related和prefetch_related
  • 5 > ORM常见字段
  • 6 > 重要参数
  • 7 > 事务操作
  • 8 > ORM执行原生SQL
  • 9 > 多对多三种创建方式
    • 9.1 > 全自动(常见)
    • 9.2 > 全手动(使用频率最低)
    • 9.3 > 半自动(常见)

1 > 聚合查询

   MySQL聚合函数有以下几种:

max\min\sum\count\avg

   Django中聚合函数也是有以上几种,关键字是aggregate,具体操做如下:

'''没有分组也可以使用聚合函数 默认整体就是一组'''# 查询book表中价格最高的价格from django.db.models import Max,Min,Sum,Avg,Countres = models.Book.objects.aggregate(Max('price'))print(res){'price__max': Decimal('29888.88')}# 查询book表中的最高价格、最低价格、价格求和、平均价格、书籍数量res = models.Book.objects.aggregate(Max('price'), Min('price'),Sum('price'),Avg('price'),Count('pk'))print(res){'price__max': Decimal('29888.88'),'price__min': Decimal('1699.80'), 'price__sum': Decimal('146028.12'),'pk__count': 8}

2 > 分组查询

   Mysql分组操做关键字是group by。
   orm的分组操做关键字是annotate。
   若orm操做执行分组操做的时候产生报错,可能需要去修改sql_mode,移除only_full_group_by。

''' 分组查询小练习 ''''''按照表名分组'''# 统计每本书的作者个数from django.db.models import Count,Min,Sumres = models.Book.objects.annotate(author_num=Count('authors__pk')).values('title','author_num')print(res)# 统计每个出版社卖的最便宜的书的价格res = models.Publish.objects.annotate(price=Min('book__price')).values('name','book__title','price')print(res)# 统计不止一个作者的图书res = models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title','author_num')print(res)# 统计每个作者出的书的总价格res = models.Author.objects.annotate(book_price_sum=Sum('book__price')).values('name', 'book_price_sum')print(res)"""上述操作都是以表为单位做分组 如果想要以表中的某个字段分组如何操作"""# 统计每个出版社主键值对应的书籍个数res = models.Book.objects.values('publish_id').annotate(book_num=Count('pk')).values('publish_id','book_num')print(res)

3 > F与Q查询

 当表中已经有数据的情况下 添加额外的字段 需要指定默认值或者可以为null方式1IntegerField(verbose_name='销量',default=1000)方式2IntegerField(verbose_name='销量',null=True)方式3在迁移命令提示中直接给默认值

3.1 > F查询

   查询库存大于销量的书籍

 res = models.Book.objects.filter(kucun > maichu)    # 不行res = models.Book.objects.filter(kucun__getmaichu)  # 不行

   当查询条件的左右两边的数据都需要表中的数据 可以使用F查询

 from django.db.models import Fres = models.Book.objects.filter(kucun__gt=F('maichu'))print(res)

   将所有书的价格提升1000块

from django.db.models import Fmodels.Book.objects.filter(price=F('price')+1000)

   将所有书的名称后面加上_爆款后缀

 '''如果要修改char字段(千万不能用上面对数值类型的操作!!!)需要使用下列两个方法'''from django.db.models.functions import Concatfrom django.db.models import Valueres = models.Book.objects.update(name=Concat(F('title'), Value('爆款')))

3.2 > Q查询

   查询价格大于20000或者卖出大于1000的书籍

 '''filter括号内多个条件默认是and关系 无法直接修改'''res = models.Book.objects.filter(price__gt=20000,maichu__gt=1000)print(res)print(res.query)'''使用Q对象 就可以支持逻辑运算符'''res = models.Book.objects.filter(Q(price__gt=20000), Q(maichu__gt=1000))  # 逗号是and关系'''<QuerySet [<Book: 书籍对象:python>,<Book: 书籍对象:linux云计算>,<Book: 书籍对象:聊斋志异>]>'''res = models.Book.objects.filter(Q(price__gt=20000) | Q(maichu__gt=1000))  # 管道符是or关系'''<QuerySet [<Book: 书籍对象:python>, <Book: 书籍对象:linux云计算>, <Book: 书籍对象:golang高并发>,<Book: 书籍对象:mysql数据库>, <Book: 书籍对象:数据分析>,<Book: 书籍对象:败家日记>, <Book: 书籍对象:聊斋志异>, <Book: 书籍对象:资本论>]>'''res = models.Book.objects.filter(~Q(price__gt=5000))print(res)  # ~是not操作'''<QuerySet [<Book: 书籍对象:聊斋志异>]>'''

   Q对象进阶用法

 '''当我们需要编写一个搜索功能 并且条件是由用户指定 这个时候左边的数据就是一个字符串'''q_obj = Q()q_obj.connector = 'or'  # 默认是and 可以改为orq_obj.children.append(('price__gt',20000))q_obj.children.append(('maichu__gt',1000))res = models.Book.objects.filter(q_obj)print(res.query)

4 > ORM查询优化

   在IT行业 针对数据库 需要尽量做 能不’麻烦’它就不’麻烦’它
   orm查询默认都是惰性查询(能不消耗数据库资源就不消耗)

 光编写orm语句并不会直接指向SQL语句 只有后续的代码用到了才会执行

   orm查询默认自带分页功能(尽量减轻单次查询数据的压力)

4.1 > only与defer

   only会产生对象结果集 ,对象点括号内出现的字段不会再走数据库查询
   但是如果点击了括号内没有的字段也可以获取到数据 但是每次都会走数据库查询
   具体操做如下:

res = models.Book.objects.only('title', 'price')for obj in res: print(obj.title)print(obj.price)print(obj.publish_time)         # 点括号内不存在的数据


   defer与only刚好相反 对象点括号内出现的字段会走数据库查询
   如果点击了括号内没有的字段也可以获取到数据 每次都不会走数据库查询
  

res = models.Book.objects.defer('title', 'price')for obj in res:print(obj.title)print(obj.price)print(obj.publish_time)         # 点击括号内没有的字段


4.2 > select_related和prefetch_related

   select_related括号内只能传一对一和一对多字段的外键字段 不能传多对多字段。
   效果是内部直接连接表(inner join) 然后将连接之后的大表中所有的数据全部封装到数据对象中。
   后续对象通过正反向查询跨表 内部不会再走数据库查询。

''' select_related '''res = models.Book.objects.select_related('publish')for obj in res:print(obj.title)print(obj.publish.name)print(obj.publish.addr)


   prefetch_related会将多次查询之后的结果封装到数据对象中 。
   后续对象通过正反向查询跨表 内部不会再走数据库查询。

''' prefetch_related '''res = models.Book.objects.prefetch_related('publish')for obj in res:print(obj.title)print(obj.publish.name)print(obj.publish.addr)

5 > ORM常见字段

   AutoField()

 int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列

   CharField()

 字符类型,必须提供max_length参数, max_length表示字符长度。这里需要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段但是Django允许我们自定义新的字段。具体操做如下from django.db import models# Create your models here.#Django中没有对应的char类型字段,但是我们可以自己创建class FixCharField(models.Field):'''自定义的char类型的字段类'''def __init__(self,max_length,*args,**kwargs):self.max_length=max_lengthsuper().__init__(max_length=max_length,*args,**kwargs)def db_type(self, connection):'''限定生成的数据库表字段类型char,长度为max_length指定的值:param connection::return:'''return 'char(%s)'%self.max_length#应用上面自定义的char类型class Class(models.Model):id=models.AutoField(primary_key=True)title=models.CharField(max_length=32)class_name=FixCharField(max_length=16)gender_choice=((1,'男'),(2,'女'),(3,'保密'))gender=models.SmallIntegerField(choices=gender_choice,default=3)

   IntergerField()

 整数列(有符号的) -2147483648 ~ 2147483647

   DecimalField()

10进制小数参数:max_digits,小数总长度decimal_places,小数位长度

   DateField()

 日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。参数:auto_now:   每次保存对象时,自动将字段设置为现在。用于“最后修改”的时间戳。注意当前日期是使用 always;它不只是一个默认值,你可以覆盖。auto_now_add:在首次创建对象时自动将字段设置为现在。用于创建时间戳。注意当前日期是使用 always;它不只是一个默认值,你可以覆盖。

   DateTimeField()

 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。参数:auto_now:    auto_now_add:

   BigIntergerField()

 长整型(有符号的)           -9223372036854775808 ~ 9223372036854775807

   BooleanField()

 布尔值类型

   TextField()

 文本类型

   FileField()

 字符串,路径保存在数据库,文件上传到指定目录参数:upload_to = ""      上传文件的保存路径storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

   EmailField()

 字符串类型,Django Admin以及ModelForm中提供验证机制

6 > 重要参数

   primary_key

 将字段设置主键字段   一个Model只允许设置一个字段为primary_key

   max_length

 最大长度

   verbose_name

 给字段加备注

   null

 用于表示某个字段可以为空。

   default

 默认值

   max_digits

 DecimalField(max_digits=8, decimal_places=2)# 表示该小数总位数为8位,小数位占2位

   decimal_places

 DecimalField(max_digits=8, decimal_places=2)# 表示该小数总位数为8位,小数位占2位

   unique

 如果设置为unique=True 则该字段在此表中必须是唯一的 。

   db_index

 为该字段设置默认值。

   auto_now

 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

   auto_now_add

 配置上auto_now=True,每次更新数据记录的时候会更新该字段。

   choices

 用于可以被列举完全的数据eg:性别 学历 工作经验 工作状态class User(models.Model):username = models.CharField(max_length=32)password = models.IntegerField()gender_choice = ((1,'男性'),(2,'女性'),(3,'变性'))gender = models.IntegerField(choices=gender_choice)user_obj.get_gender_display()  # 有对应关系就拿 没有还是本身

   to

 设置要关联的表。

   to_field

 设置要关联的字段。

   db_constraint

 db_constraint=False,这个就是保留跨表查询的便利(双下划线跨表查询),但是不用约束字段了,一半公司都用false,这样就省的报错,因为没有了约束(Field字段对象,既约束,又建立表与表之间的关系)

   外键字段中可能还会遇到related_name参数

外键字段中使用related_name参数可以修改正向查询的字段名

7 > 事务操作

MySQL事务:四大特性(ACID)原子性一致性独立性持久性start transcation;rollback;commit;'''创建事务代码'''from django.db import transactiontry:with transaction.atomic():passexcept Exception:pass

8 > ORM执行原生SQL

  用于在orm当中去写原生sql语句代码

# 方式1            使用模块from django.db import connection, connectionscursor = connection.cursor()  cursor = connections['default'].cursor()cursor.execute("""SELECT * from auth_user where id = %s""", [1])cursor.fetchone()# 方式2            直接写代码models.UserInfo.objects.extra(select={'newid':'select count(1) from app01_usertype where id>%s'},select_params=[1,],where = ['age>%s'],params=[18,],order_by=['-age'],tables=['app01_usertype'])

9 > 多对多三种创建方式

9.1 > 全自动(常见)

orm自动创建第三张表 但是无法扩展第三张表的字段authors = models.ManyToManyField(to='Author')

9.2 > 全手动(使用频率最低)

优势在于第三张表完全自定义扩展性高 劣势在于无法使用外键方法和正反向class Book(models.Model):title = models.CharField(max_length=32)class Author(models.Model):name = models.CharField(max_length=32)class Book2Author(models.Model):book_id = models.ForeignKey(to='Book')author_id = models.ForeignKey(to='Author')

9.3 > 半自动(常见)

 正反向还可以使用 并且第三张表可以扩展 唯一的缺陷是不能用add\set\remove\clear四个方法class Book(models.Model):title = models.CharField(max_length=32)authors = models.ManyToManyField(to='Author',through='Book2Author',  # 指定表through_fields=('book','author')  # 指定字段)class Author(models.Model):name = models.CharField(max_length=32)'''多对多建在任意一方都可以 如果建在作者表 字段顺序互换即可'''books = models.ManyToManyField(to='Author',through='Book2Author',  # 指定表through_fields=('author','book')  # 指定字段)class Book2Author(models.Model):book = models.ForeignKey(to='Book')author = models.ForeignKey(to='Author')

orm查询方式与优化相关推荐

  1. 灵活使用 SQLAlchemy 中的 ORM 查询

    之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性. 这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践. ...

  2. 查询性能优化(使用 Explain 进行分析、优化数据访问、重构查询方式)、存储引擎(InnoDB/MyISAM)

    1.查询性能优化 1.1 使用 Explain 进行分析 Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句. 比较重要的字段有: select ...

  3. mysql数据库子查询的使用_MySQL数据库使用子查询方式更新数据优化及思考

    [环境介绍] 云数据库MySQL 5.7 [背景描述] 业务需要:需要对16370077的表数据进行更新部分数据操作 UPDATE P_MOXXXX_REXXXX SET FISAVAILABLE = ...

  4. 【转】建立一个更高级别的查询 API:正确使用Django ORM 的方式

    这个就比较深入啦... http://www.oschina.net/translate/higher-level-query-api-django-orm 结论: 在视图和其他高级应用中使用源生的O ...

  5. 开源面向对象数据库 db4o 之旅: db4o 查询方式“db4o 之旅(二)”

    前言 在 开源面向对象数据库 db4o 之旅 系列文章的第一部分:初识 db4o 中,作者介绍了 db4o 的历史和现状,应用领域,以及和 ORM 等的比较.在这篇文章中,作者将会介绍 db4o 的安 ...

  6. SQL Server 2016 查询存储性能优化小结

    SQL Server 2016已经发布了有半年多,相信还有很多小伙伴还没有开始使用,今天我们来谈谈SQL Server 2016 查询存储性能优化,希望大家能够喜欢 作为一个DBA,排除SQL Ser ...

  7. .Net转Java自学之路—Hibernate框架篇三(查询方式)

    Hibernate查询方式: 1.对象导航查询:根据id查询出一的数据,再根据一的查询结果查询多的数据. OnlyClass only=session.get(OnlyClass.class,1); ...

  8. python-django-ORM,常用查询方式

    介绍django model 的一些常用查询方式 首先是一些文档性的帮助 __exact 精确等于 like 'aaa' __iexact 精确等于 忽略大小写 ilike 'aaa' __conta ...

  9. mysql性能优化-慢查询分析、优化索引和配置

    目录 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询 2索引及查询优化 三.配置优化 1)      max_con ...

最新文章

  1. 合并多个Word文档
  2. 十八种方法让你集中精力工作
  3. c语言中合法转义字符,判断c语言合法转义字符
  4. console.log()与alert()的区别
  5. ros发布节点信息python_ROS入门笔记(一): ROS简介
  6. Cesium 加载天地图
  7. Message Queue基本使用说明
  8. 群辉做无盘服务器,累了,最后的福利:NAS做家用无盘近完美资源包
  9. Vivado ROM IP核
  10. 最基础的傅里叶变换公式推导
  11. Leaflet vs. OpenLayers3哪个是更好的JavaScript 地图客户端
  12. PyQt5-UI界面控件布局实战-界面水平,竖直、网格混合布局(三)
  13. HCIP RS IERS题之OSPF(一)
  14. Error: ImageIO: PNG invalid PNG file: iDOT doesn't point to valid IDAT chunk 解决
  15. 阿里云数据库(hk)连接不上处理方法
  16. java 图片 大小_在JAVA中调整图片大小
  17. matlab错位相减,matlab随手记
  18. SQL语句编写经典50题
  19. 阿里巴巴java工程师应聘条件_【全国】—前端/Java工程师—阿里巴巴(长期招聘)...
  20. Java读取相片信息

热门文章

  1. java通过itext方法往pdf中插入图片(交互式pdf插入图片无法显示)
  2. Excel — 动态图表(复选框实现动态图)
  3. 来自Java程序员的Python新手入门小结
  4. DIV滚动条自动滚动到最底部的两种方法
  5. 2021个人年度总结
  6. “百钱买百鸡”的问题,题的意思是这样的,5文钱可以买一只公鸡,3文钱可以买一只母鸡,1文钱可以买3只雏鸡,现在用100文钱买100只鸡,鸡各有几只?
  7. 深入解析棋牌湖南放炮罚,跑胡子手游源码(java版)
  8. 2017车载后市场年终回顾:天下武功,唯快不破
  9. 设置手机最小宽度为1000,无限重启怎么办
  10. 清华毕业程序员国企干了14年,去应聘小公司,看到工资后愣了