ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化
聚合函数
| 名称 | 作用 |
|---|---|
| Max() | 最大值 |
| Min() | 最小值 |
| Sum() | 求和 |
| Count() | 计数 |
| Avg() | 平均值 |
关键字: aggregate
聚合查询通常都是配合分组一起使用的
关于数据库的模块
基本上都在django.db.models里面
如果上述没有那么应该在django.db里面
# 要导入模块
from django.db.models import Max, Min, Sum, Count, Avg
# 1.所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
print(res) # {'price__avg': 311.262}
# 2.使用所有的功能
res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('id'), Avg('price'))
print(res)

分组查询
关键字: annotate
格式:
# 按表分组
models.表名.objects.annotate() # models后面跟什么就按什么分组
# 按字段分组
models.表名.objects.values('字段').annotate() # annotate前有values就按指定字段分组 没有就按表名分组
用法
# 1.统计每一本书的作者的个数j书名
res = models.Book.objects.annotate(author_num=Count('author')).values('title', 'author_num')
print(res)

# 2.统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
print(res)

# 3.统计不止一个作者的图书
res = models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title', 'author_num')
print(res)

# 4.查询每个作者出的书的总价格
res = models.Author.objects.annotate(total_price=Sum('book__price')).values('name', 'total_price')
print(res)
按年月分组
id content create_time month # 这个字段是django虚拟出的字段
1 111 2020-11-11 2020-11
2 222 2020-11-12 2020-11
3 333 2020-11-13 2020-11
4 444 2020-11-14 2020-11
5 555 2020-11-15 2020-11
"""
django官网提供的一个orm语法
from django.db.models.functions import TruncMonth
-官方提供
from django.db.models.functions import TruncMonth
Sales.objects
.annotate(month=TruncMonth('timestamp')) # Truncate to month and add to select list
.values('month') # Group By month
.annotate(c=Count('id')) # Select the count of the grouping
.values('month', 'c') # (might be redundant, haven't tested) select month and count
eg:
# 按时间年月分组取出文章个数
date_list = models.Article.objects
.annotate(month=TruncMonth('create_time')) # 这行是产生month虚拟字段
.values('month').annotate(article_num=Count('pk')) # 这行是按month分组并计算数量
.values_list('month', 'article_num') # 取年月字段 和对应的数量
报错处理
如果出现错误,分组后查不出来 ,有可能是因为严格模式的原因
要去修改数据库的严格模式
分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取了
严格模式
ONLY_FULL_GROUP_BY
F与Q查询
F查询
作用: 能够帮助你直接获取到表中的某个字段对应的数据
from django.db.models import F
# 1.查询卖出数大于库存数的书籍
from django.db.models import F, Q
res = models.Book.objects.filter(maichu__gt=F('kucun'))
print(res)

# 2.将所有的书的价格提高50块
res = models.Book.objects.update(price=F('price')+50)
F是不能直接操作字符串拼接的
需要导入另外两个模块
from django.db.models.functions import Concat
from django.db.models import Value
就可以使用了
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.update(title=Concat(F('title'), Value('爆款')))

Q查询
filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
作用: 能够在filter里添加or关系或者not关系
# 1.查询卖出数大于100或者价格小于600的书籍
# 先导入模块
from django.db.models import Q
res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))
res1 = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))
print(res)
print(res1)

Q的高阶用法
作用: 能够将查询条件的左边也变成字符串的形式

用于: 能让用户自己选择检索功能
q = Q()
q.children.append(('maichu__gt', 100))
q.children.append(('kucun', 600))
# 这是默认关系还是and 要改成or
q.connector = 'or'
res = models.Book.objects.filter(q)
print(res)


django中如何开启事务
"""
事务
ACID
原子性
不可分割的最小单位
一致性
跟原子性是相辅相成
隔离性
事务之间互相不干扰
持久性
事务一旦确认永久生效
事务的回滚
rollback
事务的确认
commit
"""
# 目前你只需要掌握Django中如何简单的开启事务
# 事务
from django.db import transaction
try: # 异常捕获也可以不加
with transaction.atomic():
# sql1
# sql2
...
# 在with代码快内书写的所有orm操作都是属于同一个事务
except Exception as e:
print(e)
print('执行其他操作')
orm中常用字段及参数
AutoField
主键字段 primary_key=True
CharField varchar
verbose_name 字段的注释
max_length 长度
IntegerField int
BigIntegerField bigint
DecimalField
max_digits=8 # 代表的意思是222222.22
decimal_places=2
EmailFiled varchar(254)
DateField date
DateTimeField datetime
auto_now:每次修改数据的时候都会自动更新当前时间
auto_now_add:只在创建数据的时候记录创建时间后续不会自动修改了
BooleanField(Field) - 布尔值类型
该字段传布尔值(False/True) 数据库里面存0/1
TextField(Field) - 文本类型
该字段可以用来存大段内容(文章、博客...) 没有字数限制
后面的bbs作业 文章字段用的就是TextField
FileField(Field) - 字符类型
upload_to = "/data"
给该字段传一个文件对象,会自动将文件保存到/data目录下然后将文件路径保存到数据库中
/data/a.txt
后面bbs作业也会涉及
# 更多字段
直接参考博客:https://www.cnblogs.com/Dominic-Ji/p/9203990.html
# django除了给你提供了很多字段类型之外 还支持你自定义字段
class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
# 调用父类的init方法
super().__init__(max_length=max_length,*args,**kwargs) # 一定要是关键字的形式传入
def db_type(self, connection):
"""
返回真正的数据类型及各种约束条件
:param connection:
:return:
"""
return 'char(%s)'%self.max_length

# 外键字段及参数
unique=True
ForeignKey(unique=True) === OneToOneField()
# 你在用前面字段创建一对一 orm会有一个提示信息 orm推荐你使用后者但是前者也能用
db_index
如果db_index=True 则代表着为此字段设置索引
(复习索引是什么)
to_field
设置要关联的表的字段 默认不写关联的就是另外一张的主键字段
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
"""
django2.X及以上版本 需要你自己指定外键字段的级联更新级联删除
"""
数据库查询优化
orm语句的特点
惰性查询
如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数
那么orm会自动识别 直接不执行
res = models.Book.objects.all()
print(res) # 在注释掉打印操作的时候 不会出现SQL语句 但是执行打印操作的话就会出现SQL语句

only与defer
only
res = models.Book.objects.only('title')
for i in res:
print(i.title) # 查询only括号内的字段 不会走数据库
print(i.price) # 查询only括号内没有的字段 会重新走数据库查询 而all不需要走

defer(和only恰恰相反)
res = models.Book.objects.defer('title')
for i in res:
print(i.title) # 查询only括号内的字段 会重新走数据库查询
print(i.price) # 查询only括号内没有的字段 不会走数据库

总结:
defer与only刚好相反
defer括号内放的字段不在查询出来的对象里面 查询该字段需要重新走数据
而如果查询的是非括号内的字段 则不需要走数据库了
select_related与prefetch_related
select_related
res = models.Book.objects.select_related('publish') # inner join 连表操作
for i in res:
print(i.publish.name)

select_related内部直接先将book与publish连起来 然后一次性将大表里面的所有数据
全部封装给查询出来的对象
这个时候对象无论是点击book表的数据还是publish的数据都无需再走数据库查询了
select_related括号内只能放外键字段 一对多 一对一
多对多不行
prefetch_related
res = models.Book.objects.prefetch_related('publish') # 子查询
for i in res:
print(i.publish.name)
# 会比select_related查询多走一步SQL语句
prefetch_related该方法内部其实就是子查询
将子查询查询出来的所有结果也给你封装到对象中
给你的感觉好像也是一次性搞定的
总结:
这两个没有说绝对的谁比谁更好,在数据量较大的时候select_related的
连表操作可能会更慢,具体情况具体分析
ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化的更多相关文章
- Django框架(十一)—— 常用字段、参数、元信息、多对多关联关系
目录 常用字段和参数 一.ORM字段 二.ORM参数 三.关系字段 1.ForeignKey 2.OneToOneFiled 3.ManyToManyField 四.元信息 五.多对多关联关系的三种方 ...
- 07 模型层 orm相关查询 F查询Q查询 django开启事务
一.Django终端打印SQL语句 如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看 在Django项目的settings.py文件中,在最后复制 ...
- Django框架(十)--常用字段、参数、元信息、多对多关联关系
一.ORM字段 # AutoField() int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列 # IntegerField() ...
- 在论坛中出现的比较难的sql问题:3(row_number函数 分组查询)
原文:在论坛中出现的比较难的sql问题:3(row_number函数 分组查询) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所 ...
- Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)
Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...
- Django聚合与分组查询中value与annotate的顺序问题
在学习Django聚合与分组查询中,发现value与annotate的顺序不同时,查询结果大相径庭,经过一下午的研究,终于弄明白了,现在分享给大家,先上结论: 结论 value在annotate前面时 ...
- 第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数
第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; ...
- Django ORM中常用字段和参数
一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...
- parse_str() 函数把查询字符串解析到变量中。
定义和用法 parse_str() 函数把查询字符串解析到变量中. 注释:如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量. 注释:php.ini 文件中的 magic_quo ...
随机推荐
- 分布式锁用Redis与Zookeeper的使用
为什么用分布式锁? 在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会 ...
- 说说UI自动化中的PO模式
PO模式,全称PageObject模式,即页面对象模式.将页面定位与业务操作分离. po模式有以下几个优点: 1.易读性好 2.扩展性高 3.复用性强 4.维护性好 5.代码冗余率低 了解了po模式及 ...
- 浅析MySQL恶意服务器读取文件原理
前言 注:本文不涉及对MySQL协议报文研究,仅讲解原理,并且做部分演示. 搭建MySQL恶意服务器读取文件这件事,虽然直接利用门槛较高,但是由于在网上看到了一种比较新颖的利用方式(利用社会工程学引诱 ...
- Java 框架、库和软件的精选列表(awesome java)
原创翻译,原始链接 本文为awesome系列中的awesome java Awesome Java Java 框架.库和软件的精选列表 项目 Bean映射 简化 bean 映射的框架 dOOv - 为 ...
- 半吊子菜鸟学Web开发5 -- PHP开发环境配置
本文参考自:http://blog.csdn.net/angon823/article/details/54415855 Ubuntu16.04 默认 apt-get install apache2 ...
- 为什么要配置JDK环境变量?
1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin目录增加到现有的PATH ...
- 什么是通知(Advice)?
特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一 个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列 ...
- 不同版本的 Spring Framework 有哪些主要功能?
Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spring 3.0 发布于 2009 年.它完全利用了 Java5 中的改进,并为 JEE6 ...
- 一个 Spring 的应用看起来象什么?
一个定义了一些功能的接口.这实现包括属性,它的 Setter , getter 方法和函数等.Spring AOP.Spring 的 XML 配置文件.使用以上功能的客户端程序.
- 学习saltstack (五)
Saltstack介绍 Salt三种运行方式 1.local本地运行2.Master/Minion3.Salt ssh Salt的三大功能 a.远程执行b.配置管理(状态管理)c.云管理:阿里云,aw ...