ORM分组操作示例(与SQL语句的比较)[通俗易懂]

ORM分组操作示例(与SQL语句的比较)[通俗易懂]
class Employee(models.Model): name = models.CharField(max_length=16) age = mod…

	ORM分组操作示例(与SQL语句的比较)[数据库教程]

class Employee(models.Model):
    name = models.CharField(max_length=16)
    age = models.IntegerField()
    salary = models.IntegerField()
    province = models.CharField(max_length=32)
    dept = models.CharField(max_length=16)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "employee"

 

  操作:

我们使用原生SQL语句,按照部分分组求平均工资:

select dept,AVG(salary) from employee group by dept;

ORM语句与SQL语句对应关系:

 

ORM查询:

  ret = models.Employee.objects.all()
    print(ret)#<QuerySet [<Employee: 小黑>, <Employee: 小白>, <Employee: 赵导>, <Employee: 化工哥>]>
              #(0.003) SELECT `employee`.`id`, `employee`.`name`, `employee`.`age`, `employee`.`salary`, `employee`.`province`, `employee`.`dept` 
         FROM `employee` LIMIT 21; args=()
    ret = models.Employee.objects.values("dept")
    print(ret)
    # (0.002)  SELECT `employee`.`dept` FROM `employee` LIMIT  21; args = ()
    # < QuerySet[{‘dept‘: ‘保安部‘}, {‘dept‘: ‘影视部‘}, {‘dept‘: ‘影视部‘}, {‘dept‘: ‘福利部‘}] >
 ret = models.Employee.objects.values("dept").annotate(avg=Avg("salary")).values("dept","avg")
    print(ret)
    #(0.068) SELECT `employee`.`dept`, AVG(`employee`.`salary`) AS `avg` FROM `employee` GROUP BY `employee`.`dept` ORDER BY NULL LIMIT 21; 
    #<QuerySet [{‘dept‘: ‘保安部‘, ‘avg‘: 2000.0}, {‘dept‘: ‘影视部‘, ‘avg‘: 6500.0}, {‘dept‘: ‘福利部‘, ‘avg‘: 8000.0}]> 

多表操作

建表:

class Employee2(models.Model):
    name = models.CharField(max_length=16)
    age = models.IntegerField()
    salary = models.IntegerField()
    province = models.CharField(max_length=32)
    dept = models.ForeignKey(to="Dept")

    def __str__(self):
        return self.name

    class Meta:
        db_table = "employee2"


class Dept(models.Model):
    name = models.CharField(max_length=16, unique=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "dept2"

 

  SQL查询:

select dept2.name,AVG(salary) from employee2 inner join dept2 on (employee2.dept_id=dept2.id) group by dept_id;

ORM查询:

from django.db.models import Avg
ret = models.Employee2.objects.values("dept_id").annotate(avg=Avg("salary")).values("dept__name","avg")
print(ret)
# < QuerySet[{‘dept__name‘: ‘保安部‘, ‘avg‘: 2000.0}, {‘dept__name‘: ‘影视部‘, ‘avg‘: 6500.0}, {‘dept__name‘: ‘福利部‘, ‘avg‘: 8000.0}] >
# (0.089) SELECT `dept2`.`name`,AVG(`employee2`.`salary`) AS  `avg` FROM `employee2` INNER JOIN `dept2` ON(`employee2`.`dept_id` = `dept2`.id`) 
GROUP BY `employee2`.`dept_id`,`dept2`.`name` ORDER BY NULL LIMIT 21;args = ()
# 查所有的员工和部门名称
    ret = models.Employee2.objects.values("name", "dept__name")
    print(ret)
    #(0.012) SELECT `employee2`.`name`, `dept2`.`name` FROM `employee2` INNER JOIN `dept2` ON (`employee2`.`dept_id` = `dept2`.`id`) LIMIT 21;
    #<QuerySet [{‘name‘: ‘小黑‘, ‘dept__name‘: ‘保安部‘}, {‘name‘: ‘小白‘, ‘dept__name‘: ‘影视部‘}, {‘name‘: ‘赵导‘, ‘dept__name‘: ‘影视部‘},
{‘name‘: ‘化工哥‘, ‘dept__name‘: ‘福利部‘}]>
select_related 和 prefetch_related 的使用
def select_related(self, *fields)
    性能相关:表之间进行join连表操作,一次性获取关联的数据。

    总结:
    1. select_related主要针一对一和多对一关系进行优化。
    2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。

def prefetch_related(self, *lookups)
    性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。

    总结:
    1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
    2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。
select_related的使用示例
 #select_related的使用:表之间进行join连表操作,一次性获取关联的数据。
    ret = models.Employee2.objects.select_related()
    print(ret)
    #(0.019) SELECT `employee2`.`id`, `employee2`.`name`, `employee2`.`age`, `employee2`.`salary`, `employee2`.`province`, `employee2`.`dept_id`,
`dept2`.`id`, `dept2`.`name` FROM `employee2` INNER JOIN `dept2` ON (`employee2`.`dept_id` = `dept2`.`id`) LIMIT 21; args=() #<QuerySet [<Employee2: 小黑>, <Employee2: 小白>, <Employee2: 赵导>, <Employee2: 化工哥>]> ret = models.Employee2.objects.select_related().values("name","dept__name") print(ret) #(0.020) SELECT `employee2`.`name`, `dept2`.`name` FROM `employee2` INNER JOIN `dept2` ON (`employee2`.`dept_id` = `dept2`.`id`) LIMIT 21; #<QuerySet [{‘name‘: ‘小黑‘, ‘dept__name‘: ‘保安部‘}, {‘name‘: ‘小白‘, ‘dept__name‘: ‘影视部‘}, {‘name‘: ‘赵导‘, ‘dept__name‘: ‘影视部‘},
{‘name‘: ‘化工哥‘, ‘dept__name‘: ‘福利部‘}]>
  建立多对多关系表:
class Author(models.Model):
    name = models.CharField(max_length=32)
    books = models.ManyToManyField(to="Book")

    def __str__(self):
        return self.name

    class Meta:
        db_table = "author"

class Book(models.Model):
    title = models.CharField(max_length=32)

    def __str__(self):
        return self.title

    class Meta:
        db_table = "book"

 

 ret = models.Author.objects.select_related("books__title").values("name", "books__title")
    print(ret)
    #(0.014) SELECT `author`.`name`, `book`.`title` FROM `author` LEFT OUTER JOIN `author_books` ON (`author`.`id` = `author_books`.`author_id`)
LEFT OUTER JOIN `book` ON (`author_books`.`book_id` = `book`.`id`) LIMIT 21; args=() #<QuerySet [{‘name‘: ‘小黑‘, ‘books__title‘: ‘沙河出版社‘}, {‘name‘: ‘小白‘, ‘books__title‘: ‘沙河出版社‘}, {‘name‘: ‘小黑‘,
‘books__title‘: ‘光子出版社‘}, {‘name‘: ‘小黄‘, ‘books__title‘: ‘光子出版社‘}, {‘name‘: ‘小黑‘, ‘books__title‘: ‘番茄物语‘},
{‘name‘: ‘小白‘, ‘books__title‘: ‘番茄物语‘}, {‘name‘: ‘小黄‘, ‘books__title‘: ‘番茄物语‘}]>

批量操作

def bulk_create(self, objs, batch_size=None):
    # 批量插入
    # batch_size表示一次插入的个数
    objs = [
        models.DDD(name=‘r11‘),
        models.DDD(name=‘r22‘)
    ]
    models.DDD.objects.bulk_create(objs, 10)

示例:

    # 批量创建
    # 有100个书籍对象
    objs = [models.Book(title="沙河{}".format(i)) for i in range(6)]
    #
    # 在数据库中批量创建, 2次一提交
    models.Book.objects.bulk_create(objs, 2)

ORM分组操作示例(与SQL语句的比较)

原文地址:https://www.cnblogs.com/myws9898/p/13769419.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/6675.html

(0)
上一篇 2023-04-05
下一篇 2023-04-05

相关推荐

  • python之包(Python 常用包)

    python之包(Python 常用包)   Python之所以受欢迎不光是因为它简单易学,更重要的是它有成千上万的宝藏库。这些库相当于是已经集成好的工具,只要安装就能在Python里使用。它们可以处理各式各样的问题,无需你再造轮子,而且随着社区的不断更新维护,有些库越来越强大,几乎能媲美企业级应用。那么这些工具库怎么下载安装呢?它们被放在一个统一的“仓库”里,名叫PyPi(Python Package Index),所有的库安装都是从这里调度。有了仓库之后,还需要有管理员,pip就是这样一个角色。

    2023-10-29
    69
  • python与nlp(Python呢)「建议收藏」

    python与nlp(Python呢)「建议收藏」人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应

    2023-08-25
    97
  • Python正则表达式:用字符模式匹配和替换文本

    Python正则表达式:用字符模式匹配和替换文本在正式介绍Python正则表达式之前,需要先了解一些正则表达式的基础知识。正则表达式是一种描述字符串结构的方法,帮助我们在文本中查找、匹配和替换特定的字符或字符串。正则表达式通常由字符、元字符和模式组成。其中,字符指的是正则表达式中的普通字母和数字,用来匹配对应的字符或数字。而元字符是特殊字符,具有特殊的含义,常用来描述模式,如通配符、边界、重复等。模式是由字符和元字符组成的匹配规则。

    2023-12-14
    68
  • SQL Server 查看当前会话状态【sp_WhoIsActive 转载】

    SQL Server 查看当前会话状态【sp_WhoIsActive 转载】一.常见简便的方式 通常,DBA使用sp_who和sp_who2系统存储过程或活动监视器来查看SQL实例中的当前会话、用户和进程。 我们还可以从这些过程中确定阻塞会话和活动会话。 1.1. Sp_wh

    2023-04-18
    139
  • 用Python轻松实现字体格式转换

    用Python轻松实现字体格式转换字体格式转换指的是将一种字体格式转换成另一种字体格式。在日常生活中,我们常常会遇到需要将一种格式的字体转换成另一种格式的情况。比如,有些软件只支持某种字体格式,但我们手上的文件是另一种格式,这就需要将文件中的字体进行转换。在以下的文章中,我们将会使用Python语言,展示如何通过简单的代码实现字体格式的转换。

    2024-03-24
    29
  • mariadb修改root密码_ubuntu忘记root密码

    mariadb修改root密码_ubuntu忘记root密码linux中mysql忘记root密码如何登陆 1.关闭mysql服务 systemctl stop mysqld netstat -tunlp|grep mysqld 2.进入配置文件添加一条命令…

    2023-03-30
    619
  • 【2019年8月】OCP 071认证考试最新版本的考试原题-第20题[通俗易懂]

    【2019年8月】OCP 071认证考试最新版本的考试原题-第20题[通俗易懂]Choose two The PRODUCT_INFORMATION table has a UNIT_PRICE column of data type NUMBER(8, 2). Evaluat…

    2022-12-15
    101
  • 中间表是什么?和报表有什么关系?会带来怎样的问题?又如何解决?「终于解决」

    中间表是什么?和报表有什么关系?会带来怎样的问题?又如何解决?「终于解决」在数据库中有一类用于保存中间计算结果的物理表,通常被称为“中间表”。中间表主要跟 OLAP(在线联机分析)业务有关,产生的原因主要有以下几方面。 中间表来源 1. 计算逻辑复杂 在 OLAP(报表或…

    2023-03-17
    393

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注