Django bulk_create()、update()与数据库事务的效率对比分析


Posted in Python onMay 15, 2020

下面以创建10000个对象为例进行测试:

# 用for循环挨个创建,共花费37秒
  for i in range(10000):
    name="String number %s"%i
    Record.objects.create(name=name)
 
# 用django事务只提交一次,共花费2.65秒
@transaction.commit_manually
def manual_transaction():
  for i in range(10000):
    name="String number %s"%i
    Record.objects.create(name=name)
  transaction.commit()
 
# 用bulk_create创建,共花费0.47秒
def builtin():
  insert_list =[]
  for i in range(10000):
    name="String number %s"%i
    insert_list.append(Record(name=name))
  Record.objects.bulk_create(insert_list)
 
# 用for循环挨个更新,共花费72秒:
def auto_transaction():
  for record inRecord.objects.all():
    record.name ="String without number"
    record.save()
 
# 用django事务只提交一次,共花费17秒
@transaction.commit_manually
def manual_transaction():
  for record inRecord.objects.all():
    record.name ="String without number"
    record.save()
  transaction.commit()
 
# 用update更新,共花费0.33秒
def builtin():
  Record.objects.all().update(name="String without number")

补充知识:django的model使用上容易遇到的坑,default=datetime.now和auto_now、null和blank、save和update、bulk_create

一、django设置字段动态默认时间的四种方式:

from django.db import models
from datetime import datetime

class User(models.Model):
  id = models.BigAutoField('主键', primary_key=True)
 
  name = models.CharField('名字', max_length=20, db_index=True, default='')
 
  create_time_one = models.DateTimeField('创建时间', default=datetime.now())
  update_time_one = models.DateTimeField('更新时间', default=datetime.now)
 
  create_time_tow = models.DateTimeField('创建时间', auto_now_add=True)
  update_time_tow = models.DateTimeField('更新时间', auto_now=True)

1. default=datetime.now()

model每次初始化,都会自动设置该字段的默认值为初始化时间。

2. default=datetime.now

model每次进行新增或修改操作,都会自动设置该字段的值为操作时间。设置后仍可以使用ORM手动修改该字段。

3. auto_now_add=True

默认值为False,若设置为True,model每次进行新增操作,都会自动设置该字段的值为操作时间。设置为True后无法使用ORM手动修改该字段,哪怕填充了字段的值也会被覆盖。

4. auto_now=True

默认值为False,若设置为True,model每次进行新增或修改操作,都会自动设置该字段的值为操作时间。设置为True后无法使用ORM手动修改该字段,哪怕填充了字段的值也会被覆盖。

5. 要注意的点

除非想设置动态默认时间为项目的启动时间,否则default=datetime.now()这种用法是错误的,会得到期望之外的结果。

使用User.objects.update方法时,设置的default=datetime.now和auto_now=True都不会生效,由于设置了auto_now=True的字段不能手动修改,此时只能使用save方法修改数据,这对于多个数据的更新是不友好的。

因此如果设置动态默认时间的字段,应该使用default=datetime.now和auto_now_add=True来实现。

二、null=True和blank=True的区别

1. null针对数据库,如果null=True,表示数据库的该字段可以为空。

2. blank针对表单的,如果blank=True,表示表单填写该字段时可以不填。

mysql中空值不占用空间,NULL占用空间,而且使用NULL会使索引的效率下降。因此从性能上来说,不建议使用null=True,最好使用default=''。

三、save和build_create的区别

1. 使用save方法:

names = ['张三', '李四']
for name in names:
  user = User(name=name)
  user.save()
  print(user.id) # 此时user对象有id的值

2. 使用bulk_create方法:

names = ['张三', '李四']
users = [User(name=name) for name in names]
users = User.objects.bulk_create(users)
print([user.id for user in users]) # 此时user对象没有id的值

bulk_create的优点:

批量操作时只与数据库进行一次交互,效率高。

bulk_create的缺点:

对于设置了自增的字段,返回值中不会有该字段的值,如上例2中的user对象。

对于设置了动态默认时间的字段,如设置了auto_now=True,同一批处理的记录中该字段的时间将会相同。

四、上面的知识点使用的例子

1. 定义模型

from django.db import models
from datetime import datetime
 
class User(models.Model):
  id = models.BigAutoField('主键', primary_key=True)
  name = models.CharField('名字', max_length=20, db_index=True, blank=False, default='')
  create_time = models.DateTimeField('创建时间', auto_now_add=True)
  update_time = models.DateTimeField('更新时间', default=datetime.now)

2. 插入数据

# 方法一
names = ['张三', '李四']
users = [User(name=name) for name in names]
users = User.objects.bulk_create(users)
 
# 方法二
names = ['张三', '李四']
users = [User(name=name) for name in names]
[user.save() for user in users]

3. 修改数据

# 方法一
names = ['张三', '李四']
User.objects.filter(name__in=names).update(name='changed', update_time=datetime.now()) # 这里必须显式对update_time赋值
 
# 方法二
names = ['张三', '李四']
users = User.objects.filter(name__in=names)
for use in users:
  user.name = 'changed'
  user.save() # 这里会自动更新update_time,但是多次save效率低

以上这篇Django bulk_create()、update()与数据库事务的效率对比分析就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的类与对象之描述符详解
Mar 27 Python
python中引用与复制用法实例分析
Jun 04 Python
python压缩文件夹内所有文件为zip文件的方法
Jun 20 Python
python通过socket查询whois的方法
Jul 18 Python
最大K个数问题的Python版解法总结
Jun 16 Python
Python判断变量是否为Json格式的字符串示例
May 03 Python
小白入门篇使用Python搭建点击率预估模型
Oct 12 Python
matplotlib实现热成像图colorbar和极坐标图的方法
Dec 13 Python
解决django 新增加用户信息出现错误的问题
Jul 28 Python
解决pytorch DataLoader num_workers出现的问题
Jan 14 Python
django下创建多个app并设置urls方法
Aug 02 Python
python 如何在list中找Topk的数值和索引
May 20 Python
Python实现aes加密解密多种方法解析
May 15 #Python
django 数据库 get_or_create函数返回值是tuple的问题
May 15 #Python
重写django的model下的objects模型管理器方式
May 15 #Python
Python基于pip实现离线打包过程详解
May 15 #Python
Django在Model保存前记录日志实例
May 14 #Python
django 连接数据库出现1045错误的解决方式
May 14 #Python
Django ORM filter() 的运用详解
May 14 #Python
You might like
PHP不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
PHP设计模式之命令模式的深入解析
2013/06/13 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
php获取POST数据的三种方法实例详解
2016/12/20 PHP
学习jquery必备 api中英文对照的chm手册 下载
2007/05/03 Javascript
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
浅析javascript中function 的 length 属性
2014/05/27 Javascript
JQuery的ON()方法支持的所有事件罗列
2015/02/28 Javascript
JavaScript使用push方法添加一个元素到数组末尾用法实例
2015/04/06 Javascript
Javascript必知必会(四)js类型转换
2016/06/08 Javascript
使用nodejs中httpProxy代理时候出现404异常的解决方法
2016/08/15 NodeJs
javascript中Number的方法小结
2016/11/21 Javascript
three.js快速入门【推荐】
2017/01/21 Javascript
ionic App问题总结系列之ionic点击系统返回键退出App
2017/08/19 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
基于bootstrap页面渲染的问题解决方法
2018/08/09 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
Python程序设计入门(3)数组的使用
2014/06/16 Python
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
浅谈python为什么不需要三目运算符和switch
2016/06/17 Python
python实现屏保计时器的示例代码
2018/08/08 Python
Python中IP地址处理IPy模块的方法
2019/08/16 Python
python如何爬取网页中的文字
2020/07/28 Python
Python Celery异步任务队列使用方法解析
2020/08/10 Python
html5 冒号分隔符对齐的实现
2019/07/31 HTML / CSS
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
服装设计专业毕业生推荐信
2013/11/09 职场文书
《我不是最弱小的》教学反思
2014/02/23 职场文书
教师年度个人总结
2015/02/11 职场文书
房地产财务经理岗位职责
2015/04/08 职场文书
2015国庆节66周年标语
2015/07/30 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
纪检干部学习心得体会
2016/01/23 职场文书