首页 > 数据库 >django:数据库的一些进阶知识点与应用

django:数据库的一些进阶知识点与应用

时间:2023-04-01 12:12:38浏览次数:54  
标签:知识点 事务 进阶 数据库 db django import 连接池

一,连接池

使用第三方程序向数据库发出数据操作请求前,都需要先创建到数据库的连接,这个操作会占用大量资源。

所谓的资源消耗,一是对数据库连接数量的消耗;二是对系统内存资源的消耗;三是连接建立过程对时间的消耗,时间消耗角度可以参考这篇博客

django默认会在请求进来的时候创建数据库连接,并在请求完成后关闭连接。从以上三方面的资源消耗来说,较多的连接会明显降低应用响应速度、增加服务器端压力。

使用连接池就是一个简单的缓解这种压力的办法。

设想一下,如果将创建好的连接放入一个“池pool”中,在需要时取出使用,不需要时再放回池中,资源的消耗情况会得到缓解。

使用连接池,需要这么一些步骤:

  1. 连接池的创建
  2. 连接池中连接的使用管理
  3. 连接池的关闭

django本身是不支持连接池的,但它有众多的第三方应用可供使用,比如django-db-connection-pool、django-database-pool、django_db_poolling等。这里以使用django_db_poolling为例:

安装:
pip install pymyswl, django_db_poolling

在wsgi.py文件中修改:
import os
import pymysql

from django.core.wsgi import get_wsgi_application

from django_db_pooling import pooling

pymysql.install_as_MySQLdb()

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDjango.settings')

application = get_wsgi_application()

pooling.set_pool_size(4) # 设置连接池大小
pooling.apply_patch()

配置settings.py:
CONN_MAX_AGE = 60

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

连接池技术需要考虑到事务ACID特性处理,为了避免多线程共享同一连接破坏隔离性,最好还是用每一个事务独占一个连接来实现。

二,再提懒加载与缓存

稍微了解过QuerySet 对象的都知道,它采用“懒加载”机制。
例如使用返回QuerySet对象的all()方法进行查询时:

>>> City.objects.all()
  • 1

all()不会立即从数据库中执行查找操作,而直到它参与到计算当中,它真正执行查询操作:

>>> q = City.objects.all()
>>> q
<QuerySet [<City: 成都>, <City: 绵阳>, <City: 南充>]>
>>> type(q)
<class 'django.db.models.query.QuerySet'>
  • 1
  • 2
  • 3
  • 4
  • 5

上面这个特性就是所谓的“懒加载”。

一般情况下,一旦当通过QuerySet对象获取到数据,这个数据会被缓存到这个QuerySet中,这样就能在多处获取这些数据的不同部分,这对减少数据库操作请求非常有用。比如在q = City.objects.all()的基础上进一步执行其他操作:

>>> [p.name for p in q]
['成都', '绵阳', '南充']
>>> q.order_by('-id')
<QuerySet [<City: 南充>, <City: 绵阳>, <City: 成都>]>
  • 1
  • 2
  • 3
  • 4

但是,在使用列表索引或切片的情况下,不会使用缓存,如:

>>> q = City.objects.all()[:3] #查询一次数据库
>>> [p.id for p in q]
[1, 2, 3]
>>> q = City.objects.all()[:2] #会再次查询数据库
>>> [p.id for p in q]
[1, 2]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用好这种懒加载特性与缓存机制,能有效降低向数据库发送请求的次数。

幸运的是,大多数查询方法的结果都是支持懒加载与缓存的。

三,事务

1,什么是事务

先举个栗子:顾客有100元,商家有100元。顾客消费后需向商家转账20元,如果在顾客转账操作提交后、在商家账户增加20元之前发生系统故障导致转账中断,就可能导致顾客账户已经减少20元但商家账户账目不变的情况。为了避免这种情况,需要使用事务。

所谓事务是用户定义的一个数据库操作序列, 这些操作要么全做, 要么全不做, 是一个不可分割的工作单位。

事务具有4个特性——ACID

  1. 原子性(Atomicity):事务是数据库的逻辑工作单位, 事务中包括的诸操作要么都做, 要么都不做。
  2. 一致性(Consistency):事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。 因此当数据库只包含成功事务提交的结果时, 就说数据库处于一致性状态。 如果数据库系统运行中发生故障, 有些事务尚未完成就被迫中断, 这些未完成的事务对数据库所做的修改有一部分已写入物理数据库, 这时数据库就处于一种不正确的状态, 或者说是不一致的状态。
  3. 隔离性(Isolation):一个事务的执行不能被其他事务干扰。 即一个事务的内部操作及使用的数据对其他并发事务是隔离的, 并发执行的各个事务之间不能互相干扰。
  4. 持续性(Durability):指一个事务一旦提交, 它对数据库中数据的改变就
    应该是永久性的。 接下来的其他操作或故障不应该对其执行结果有任何影响。

在SQL中, 定义事务的语句一般有三条:

  1. 事务通常是以BEGIN TRANSACTION开始
  2. COMMIT提交事务, 即提交事务的所有操作,事务正常结束
  3. ROLLBACK回滚事务, 即在事务运行的过程中发生了某种故障, 事务不能继续执行, 系统将事务中对数据库的所有已完成的操作全部撤销, 回滚到事务开始时的状态

2,django中的事务处理

django就是通过事务与保存点来保证ORM查询操作的完整性。

django对事物的定义在transaction.py文件中:

  1. 在函数视图或类视图前添加@transaction.atomic表示使用视图
  2. savepoint()开启事务保护
  3. savepoint_commit()提交事务
  4. savepoint_rollback()回滚事务

这会将视图包含在一个事务当中。如果要阻止视图在事务中运行,使用@transaction.non_atomic_requests装饰器就行。

除此之外,还能通过设置ANTOMIC_REQUESTS = True将请求包含在事务当中。

这是一个简单的事务处理的例子:

from django.db import transaction
from django.db.models import *
from index.models import *
from django.db import connection

@transaction.atomic
def index(request):
sid = transaction.savepoint()
try:
id = request.GET.get('id', '')
if id:
v = Vocation.objects.get(id=id)
v.update(payment=F('payment') + 1)
print('Done')
else:
Vocation.objects.update(payment=F('payment') - 1)
transaction.savepoint_rollback(sid)
except Exception as e:
# 事务回滚
transaction.savepoint_rollback(sid)
return render(request, 'index.html', locals())

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

发现没有,在payment完成+1之后,我们没有执行提交操作,但数据库的payment确实是+1了的,这是因为django是默认开启自动提交的,这种隐式的操作简化了SQL中事务的操作过程。

当然这种自动提交时可以关闭的,设置AUTOCOMMIT=False即可。

标签:知识点,事务,进阶,数据库,db,django,import,连接池
From: https://www.cnblogs.com/clark1990/p/17278381.html

相关文章

  • 读SQL进阶教程笔记04_集合运算
    1. 集合论是SQL语言的根基1.1. UNION1.1.1. SQL-86标准1.2. NTERSECT和EXCEPT1.2.1. SQL-92标准1.3. 除法运算(DIVIDEBY)1.3.1. 没有被标准化2. 注意事项2.1. SQL能操作具有重复行的集合,可以通过可选项ALL来支持2.1.1. 不允许重复2.1.1.1. 直接使......
  • Django: @login_required
    Django:Tweaking@login_requireddecorator我想为我的网站开始一个私人Beta版。我有一个初始页面,用户可以在其中输入代码,然后访问网站的其余部分。当前,所有其他站点页面(初始页面除外)都包含一系列通过要求用户登录(通过@login_required装饰器)设置的重定向。我希望登录......
  • 软件构造规约设计知识点总结
    已经开始做软件构造实验二了,但做了几天还是感觉不太对,有种无从下手的感觉,我还是来复习一下本次实验所要用到的知识点吧,至于前面的知识呢,先别急,虽然也用的上,但在本次实验不是重点,之后再进行复习。知识点概要:规约设计测试用例ADT的泛化型ADT的抽象函数(AF)、......
  • DIM中的一些知识点(慢更)
    最大深度互信息模型(DIM)执行图片搜索器MINE方法:之前看下面这句话的时候总是云里雾里,好好推了下公式终于明白啦。利用神经网络计算互信息可以转换为计算两个数据集合的联合分布和边缘分布之间的散度具体推导过程:如图,首先,我们有:I(X;Y)=H(X)-H(X|Y)其中,H(X......
  • QMainWindow知识点记录
    1.新建action toolbaropenFileAction = new QAction(QIcon(":/pic/open"), QString::fromLocal8Bit("打开"), this); openFileAction->setShortcut(tr("Ctrl+O")); openFileAction->setStatusTip(tr("打开一个文件"));-------......
  • gulp笔记 2 (进阶一点点:使用bower来管理前端依赖)
    其实gulp比例1中的内容已经基本满足开发要求了。此文为进阶的一点点知识#1 安装bower(bower是个纯web前端依赖管理工具。)   npminstall-gbower #版本为1.8.14,必须安装在全局   bowerinit#会生成一个bower.json文件,选项寂寞默认就行,bower的库户自动放到bowe......
  • Python Django投稿系统代码
    PythonDjango投稿系统代码Python是一种高级编程语言,而Django则是一个基于Python的Web框架。使用Python和Django可以轻松地创建现代化、高效的Web应用程序,其中包括投稿系统。投稿系统是一个允许用户发布内容或文章的Web应用程序。Python和Django的结合使得创建投稿系统变得简单......
  • django自定义模板显示不同状态的颜色
    一般这个颜色列表是放在models.py里charge_type_class_mapping={1:"success",2:"danger",3:"default",4:"info",5:"primary",} color.pyfromdjango.templateimportLib......
  • playwright 使用日常知识点积累--不定期补充
    简介:Playwright是由微软公司2020年初发布的新一代自动化测试工具,相较于目前最常用的Selenium,它仅用一个API即可自动执行Chromium、Firefox、WebKit等主流浏览器自动化操作,并同时支持以无头模式、有头模式运行。官网地址:Playwright|Playwright.NET一:Playwright安装及介绍Pl......
  • Unity客户端开发工程师的进阶之路
    UWA技能成长系统是UWA根据学员的职业发展目标,提供技能学习的推荐路径,再将所需学习内容按难易等多维度,设计分成多个学习阶段,可以循序渐进地进行学习。每个阶段学员完成学习任务后不但可以获得技能的提升,还将获得UWA社区相应的积分奖励(积分可兑换礼品和优惠券哦)。 进入技能成长......