Django深度剖析 - ORM

概述

简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping) 的缩写。
ORM 把数据库映射成对象。

  • 数据库的表(table) --> 类(class)
  • 记录(record,行数据)–> 对象(object)
  • 字段(field)–> 对象的属性(attribute)

ORM 使用对象,封装了数据库操作,因此可以不碰 SQL 语言。开发者只使用面向对象编程,与数据对象直接交互,不用关心底层数据库。

ORM 有下面这些优点

  • 数据模型都在一个地方定义,更容易更新和维护,也利于重用代码。
  • ORM 有现成的工具,很多功能都可以自动完成,比如数据消毒、预处理、事务等等。
  • 它迫使你使用 MVC 架构,ORM 就是天然的 Model,最终使代码更清晰。
  • 基于 ORM 的业务代码比较简单,代码量少,语义性好,容易理解。
  • 你不必编写性能不佳的 SQL。

但是,ORM 也有很突出的缺点

  • ORM 库不是轻量级工具,需要花很多精力学习和设置。
  • 对于复杂的查询,ORM 要么是无法表达,要么是性能不如原生的 SQL。
  • ORM 抽象掉了数据库层,开发者无法了解底层的数据库操作,也无法定制一些特殊的 SQL。

Django ORM

在这里插入图片描述
下面从一个Blog Model定义来看Django ORM能做什么,,为了更好的理解,相关说明已经写在了注释中

# 所有的model都继承自django.db.models.Model
from django.db import models

class Person(models.Model):

	# 下面定义了数据表的每个字段和对应的数据类型
	# 如果没有定义主键,会自动添加id自增字段/且自动设置为主键
	# id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    salary = models.IntegerField()
    department = models.ForeignKey("myapp.Department",on_delete=models.SET(""))

    # Person的元数据
    class Meta:
    	# 重新定义数据表的名字为person,如果没有指定此,默认的数表名为 [appname]_person
    	db_table = 'person'

    # Person对象的实例的描述,默认显示为<Person:Person Object>
    def __str__(self):
    	return self.first_name

上面的Person模型会创建如下的数据库

CREATE TABLE person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

一个django model的经典经典定义包含如四个部分:

  1. Model Class
  2. Meta
  3. str
  4. Fields

Django ORM能做什么

在这里插入图片描述

  1. 基础查询
    实现对数据表的CRUD操作,对于select形式的查询操作,Django会返回一个QuerySet,这里可以简单理解为list(objectc)

    # 目前person表中的总记录数
    Person.objects.count()
    
    # first_name为张的用户数
    Person.objects.filter(first_name='张').count()
    
  2. 聚合函数
    Django提供俩种聚合:

    • 为整个QuerySet生成聚合值,支持的函数有Avg,Count,Max, Min等

      # 求salary的平均值
      Person.objects.all().aggregate(Avg('salary'))
      
      # 求salary的最大值
      Person.objects。all().aggregate(Max('salary'))
      
    • 为查询集的每个对象生成聚合值

  3. Q查询和F查询

    • Q查询:对对象的复杂查询

      # 查询first_name以z开头或者last_name以j开头 并且salary大于9000的Person QuerySet
      query = (Q(first_name__startwith='z') | Q(last_name__startwith='j')) & Q(salary_gt=9000)
      Person.objects.filter(query)
      
    • F查询:获取对数据表字段的引用

      # 查询first_name中包含l的Person QuerySet
      Person.objects.filter(first_name__contains=F('l'))
      

Django ORM适合做什么

Django ORM适合做OLTP(事务型)的业务开发,不适合做OLAP(分析型) 型的数据分析

  • OLTP型的业务开发一次性涉及的数据量不会太大,大多针对单用户做查询相关的操作,比如我们针对美团这样一个app, 每一个人打开美团app,都是针对当前打开人一个单用户进行数据库操作。
  • OLAP型的数据分析一次性涉及的数据量会非常大,ORM框架会对数据结果进行封装,大量的数据会导致效率明显降低。比如生成报表,会聚合数据库的所有的数据,做相关的规整,反应整个业务发展情况,这样的情况,我们使用原生的SQL会更合适。

Django ORM需要注意的地方

  1. 出现filter,exclude,order_by这样的查询的时候考虑在需要的Field上加上db_index=True
  2. 不需要所有的数据一定要使用limit,而不是拿到整个数据集之后在做切片
  3. 使用values_list获取需要的数据,而不是每条记录的所有Field
  4. 不要使用len(QuerySet),用count()代替;不要使用if QuerySet,用exists()代替
  5. 复杂的查询(比如表之家按的join),使用rqw_sql (原始的SQL) 代替

Django ORM的核心模块

django.db下有如下三个子模块

  • backends:多数据库支持(mysql/sqlite/),通用的sql代码,数据库连接,管理游标等
  • migrations:model的更新触发重建表结构的功能,我们在修改了model,在不影响现有数据的前提下重建数据表结构,在使用model创建数据表后,会在当前的app下创建一个migrations.py文件,文件里记录了有那些model以及model中定义了哪些Field。。
  • models:对象字段类型的提供,对象管理,基础查询,聚合查询等
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值