[TOC]

Django模型层之ORM介绍

一 ORM是什么?为何要有ORM?

​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(增、删、改、查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql、oracle、Microsoft SQL Server等。

​ 如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库

​ 针对应用程序的数据操作,直接编写原生sql语句会存在两方面的问题,严重影响开发效率,如下

#1. sql语句的执行效率问题:应用开发程序员需要耗费一大部分精力去优化sql语句

#2. 数据库迁移问题:针对mysql开发的sql语句无法直接应用到oracle数据库上,一旦需要迁移数据库,便需要考虑跨平台问题

​ 为了解决上述问题,django引入了ORM的概念,ORM全称Object Relational Mapping,即对象关系映射,是在pymysq之上又进行了一层封装,对于数据的操作,我们无需再去编写原生sql,取代代之的是基于面向对象的思想去编写类、对象、调用相应的方法等,ORM会将其转换/映射成原生SQL然后交给pymysql执行

​ 基于图2所示,有了ORM框架,开发人员既不用再去考虑原生SQL的优化问题,也不用考虑数据库迁移的问题,ORM都帮我们做了优化且支持多种数据库,这极大地提升了我们的开发效率,下面就让我们来详细学习ORM的使用吧

二 ORM的使用之模型

​ 在django的ORM框架中,继承自django.db.models.Model的类称之为模型类,或简称模型。

​ 一个模型是关于你的数据,唯一的、决定性的信息源、它包含存储数据的基本字段和方法。

​ 通常,每个模型都映射到一个数据库表。模型中的属性对应数据库表的字段

​ 如下所示:原生SQL与ORM的模型对应关系

三 ORM的使用之数据库迁移

3.1 创建模型

​ 数据来源于数据库的表,而ORM的模型类对应数据库表,所以若我们想操作数据,必须先创建模型。

# 创建django项目,新建名为app01的app,在app01的models.py中创建模型

class Employee(models.Model): # 必须是models.Model的子类

id=models.AutoField(primary_key=True)

name=models.CharField(max_length=16)

gender=models.BooleanField(default=1)

birth=models.DateField()

department=models.CharField(max_length=30)

salary=models.DecimalField(max_digits=10,decimal_places=1)

3.2 配置settings.py

3.2.1 注册应用

​ 但凡涉及到数据库同步操作的应用,都需要事先在settings.py的INSTALLED_APPS中完成注册

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

# django2.x+版本

'app01.apps.App01Config', # 如果默认已经添加了,则无需重复添加

# 'app02.apps.App02Config', # 若有新增的app,按照规律依次添加即可

# django1.x版本

'app01', # 直接写应用名字

# 'app02'

]

3.2.2 配置后端数据库

​ django的orm支持多种数据库(如PostgreSQL、MySQL、SQLite、Oracle等),如果想将上述模型转为mysql数据库中的表,需要settings.py中配置DATABASES,如下

# 删除\注释掉原来的DATABASES配置项,新增下述配置

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql', # 使用mysql数据库

'NAME': 'db1', # 要连接的数据库

'USER': 'root', # 链接数据库的用于名

'PASSWORD': '', # 链接数据库的用于名

'HOST': '127.0.0.1', # mysql服务监听的ip

'PORT': 3306, # mysql服务监听的端口

'ATOMIC_REQUEST': True, #设置为True代表同一个http请求所对应的所有sql都放在一个事务中执行

#(要么所有都成功,要么所有都失败),这是全局性的配置,如果要对某个

#http请求放水(然后自定义事务),可以用non_atomic_requests修饰器

'OPTIONS': {

"init_command": "SET storage_engine=INNODB", #设置创建表的存储引擎为INNODB

}

}

}

​ 强调!!!:在链接mysql数据库前,必须事先创建好数据库

mysql> create database db1; # 数据库名必须与settings.py中指定的名字对应上

3.2.3 配置日志

​ 如果想打印orm转换过程中的sql,需要在settings中进行配置日志:

LOGGING = {

'version': 1,

'disable_existing_loggers': False,

'handlers': {

'console':{

'level':'DEBUG',

'class':'logging.StreamHandler',

},

},

'loggers': {

'django.db.backends': {

'handlers': ['console'],

'propagate': True,

'level':'DEBUG',

},

}

}

3.3 mysqlclient安装与兼容性问题

​ 首先执行下述命令来创建一个迁移

$ python manage.py makemigrations

​ 会抛出异常

......

raise ImproperlyConfigured(

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.

Did you install mysqlclient?

​ 提示我们需要事先安装好mysqlclient,并且默认加载的mysqlclient是模块MySQLdb,需要安装MySQL-python,但目前python官方第三库中最新版MySQLdb 1.2.5对python解释器以及MySQL Server的支持如下,并不支持python3.0+Python解释器支持

CPython : 支持2.4到2.7

MySQL Server支持

3.23=< MySQL <= 5.5

​ 为此,有人在github中创建了一个MySQLdb1分支 来支持Cpython3.0+解释器,可以参照官网进行安装https://pypi.org/project/mysqlclient/

​ 除了使用MySQLdb作为MySQLclient之外,我们还有可以使用pymysqlPython解释器支持:

CPython : 2.7 and >= 3.5

PyPy : Latest version

MySQL Server支持:

MySQL >= 5.5

​ 比起前者,pymysql直接支持Cpython3.0+,安装简单

pip3 install pymysql

​ 但是因为Django默认加载的MySQLclient是MySQLdb,所以需要作出修改

​ 此时重新执行python manage.py makemigrations仍会抛出异常

......

File "/Users/linhaifeng/PycharmProjects/egon_test/venv-3.8/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 37, in

raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have%s.' % Database.__version__)

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.

​ 需要根据上述异常提示的文件base.py路径打开文件,注释下述两行

if version < (1, 3, 13):

raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have%s.' % Database.__version__)

​ 如果重新执行makemigrations命令,扔抛出异常

......

File “xxx\lib\site-packages\django\db\backends\mysql\operations.py”, line 146, in last_executed_query

query = query.decode(errors=‘replace’)

AttributeError: ‘str’ object has no attribute ‘decode’

​ 需要根据上述异常提示的operations.py文件路径打开文件,把146行的decode修改为encode

​ ps:PyPI(Python Package Index)是Python官方的第三方库,所有人都可以下载或上传Python库到PyPI。可以访问https://pypi.org/,自行查看各个库的版本支持,

3.4 数据库迁移命令

​ 最后在命令行中执行两条数据库迁移命令,即可在指定的数据库db1中创建表 :

$ python manage.py makemigrations

$ python manage.py migrate

# 注意:

# 1、makemigrations只是生成一个数据库迁移记录的文件,而migrate才是将更改真正提交到数据库执行

# 2、数据库迁移记录的文件存放于app01下的migrations文件夹里

# 3、了解:

如果要给迁移一个有意义的名称而不是生成的名称,则可以使用makemigrations --name选项:

python manage.py makemigrations --name xx app01 # 会在migrations目录下生成迁移文件0001_xx.py

python3 manage.py sqlmigrate app01 0001_xx # 展示迁移的sql语句

python manage.py showmigrations # 项目的迁移及其状态。

​ 注意:当我们直接去数据库里查看生成的表时,会发现数据库中的表与orm规定的并不一致,这完全是正常的,事实上,orm的字段约束就是不会全部体现在数据库的表中,比如我们为字段gender设置的默认值default=1,去数据库中查看会发现该字段的default部分为null

mysql> desc app01_employee; # 数据库中标签前会带有前缀app01_

+------------+---------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+------------+---------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| name | varchar(16) | NO | | NULL | |

| gender | tinyint(1) | NO | | NULL | |

| birth | date | NO | | NULL | |

| department | varchar(30) | NO | | NULL | |

| salary | decimal(10,1) | NO | | NULL | |

+------------+---------------+------+-----+---------+----------------+

,虽然数据库没有增加默认值,但是我们在使用orm插入值时,完全为gender字段插入空,orm会按照自己的约束将空转换成默认值后,再提交给数据库执行

3.5 模型字段的增、删、改

​ 在表生成之后,如果需要增加、删除、修改表中字段,需要这么做

# 一:增加字段

#1.1、在模型类Employee里直接新增字段,强调:对于orm来说,新增的字段必须用default指定默认值

publish = models.CharField(max_length=12,default='人民出版社',null=True)

#1.2、重新执行那两条数据库迁移命令

# 二:删除字段

#2.1 直接注释掉字段

#2.2 重新执行那两条数据库迁移命令

# 三:修改字段

#2.1 将模型类中字段修改

#2.2 重新执行那两条数据库迁移命令

3.6 加载django配置

​ 在开发django项目时,如果我们想跳过django的启动与操作流程,只测试某一部分的代码的功能,需要首先引入django的配置环境才可以

import sys

import os

import django

# 1、将项目的根目录填入环境变量

BASE_DIR = os.path.dirname(传入项目所在的根目录)

sys.path.append(BASE_DIR)

# 2、引入项目的配置环境,然后无需启动django项目就可以使用其配置环境了

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings')

django.setup()

# 可以将上述代码粘贴进交互式环境,直接在交互式环境测试

if __name__ == "__main__":

# 编写测试代码,直接运行本文件即可

from app01.models import Person

all =Person.objects.all().values()

print(all)

四 基本使用简介

​ 增加一条记录

obj=Employee(name="Egon",gender=0,birth='1997-01-27',department="财务部",salary=100.1)

obj.save()

​ 查询记录

obj = Employee.objects.filter(name="Egon").first() # 查询所有名字为Egon的记录并取第一条

print(obj.id, obj.name, obj.birth) # 输出1 Egon 1997-01-27

​ 修改记录

Employee.objects.filter(name="Egon").update(name="EGON") # 过滤出所有名字为Egon的记录并将name字段改成大写EGON

​ 删除记录

Employee.objects.filter(name="EGON").delete() # 过滤出所有名字为EGON的记录并删除

orm mysql_ORM介绍相关推荐

  1. Orm框架介绍和常见的Android Orm框架

    ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中. 先介绍一下ORM的概念,以前也一直听说 ...

  2. C++ 对象关系映射(ORM)介绍

    用过Java的都知道SSH框架,特别对于数据库开发,Java领域有无数的ORM框架,供数据持久层调用,如Hibernate,iBatis(现在改名叫MyBatis),TopLink,JDO,JPA-- ...

  3. 对象关系映射(ORM)介绍理解

    问题背景 假设,让你设计一个框架,把jdbc封装一下?? JDBC操作步骤: 获取数据库连接Connection 创建操作命令对象Statement 执行sql语句(sql中,如果有占位符,在执行sq ...

  4. sugar orm使用介绍

    首先介绍一下sugar orm为什么诞生!!! 借用官网上面的几句话: a.Fairly large and complex data model. b.Primary work was to sav ...

  5. ORM框架介绍——什么是ORM框架?

    1.什么是ORM? 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.ORM框架是连接数据库的桥梁,只要提 ...

  6. python模型的属性是什么_Python的自定义属性访问跟描述器以及ORM模型的简单介绍...

    一 . 自定义属性访问 1.__getattr__ 作用:当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发. 2.__getattribute__ 作用:访问属性的时候, ...

  7. AgileEAS.NET之ORM访问器

    上一篇文章AgileEAS.NET之数据关系映射ORM简单介绍了一下AgileEAS.NET平台中ORM对象的组织机构体系,但并没有对其所执行的数据存取操作介绍,在AgileEAS.NET中,我对OR ...

  8. Django从理论到实战(part26)--ORM模型

    学习笔记,仅供参考 参考自:Django打造大型企业官网–Huang Y: 本系列Blog以应用为主,理论基础部分我在后端专栏的Django系列博客已经写过了,如果有些需要补充的知识点,我会在这个系列 ...

  9. php中orm模型,模型model

    ## 模型model 在看模型之前,我们先看一段yaf作者鸟哥在他自己博客里的一段文字吧: > 还有不少同学问, 为什么Yaf没有ORM, 这里有俩方面的考虑: 首先, Yaf并不是万能的, 它 ...

最新文章

  1. linux常用命令,知识在于总结
  2. HTML的input类型为hidden导致无法reset改字段的value问题
  3. JS中怎样获取当前日期的前一个月和后一个月的日期字符串
  4. IOS开发之JSON序列化从客户端发送到服务器端
  5. c++101rule
  6. 集成Tomcat环境到Eclipse中
  7. win7 path环境变量被覆盖了怎么恢复_系统小技巧:还原Windows10路径环境变量
  8. zabbix监控Linux系统服务
  9. shell 获取时间
  10. Java并发编程75道面试题及答案 1
  11. 上位机、下位机、单片机的关系
  12. 上传图片到淘宝接口调用展示
  13. 腾讯单点登录系统跨域劫持漏洞
  14. 求助一维光子晶体的FDTD代码!万分感谢
  15. 10个重要的算法C语言实现源代码(留着以后看)
  16. c语言中的less函数,less的小白入门介绍
  17. 智能定位系统实验报告
  18. 安装pyltp模块详细教程(windows下python安装)
  19. 数字图像处理篇(7)角点检测
  20. 没有配置java环境变量,为什么我java环境变量都还没有配置都可以运行java程序了...

热门文章

  1. 【PC工具】震精!这个云办公云平台好强大,UZERME云端超级应用平台
  2. 三 虚拟机安装Deepin
  3. 基于相空间重构的混沌背景下微弱信号检测方法仿真
  4. centos7 无法启动网络(service network restart)错误解决办法
  5. 详解在Linux下实现(彩色)进度条程序,并通过makefile进行编译.
  6. 【火炉炼AI】机器学习007-用随机森林构建共享单车需求预测模型
  7. CSS margin详解
  8. 转:WebClient类(温习一下)
  9. 802.11协议中帧控制域中To DS and From DS 比特位的含义
  10. PAT甲级1071 Speech Patterns :[C++题解]字符串哈希