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进行mp3格式判断
Dec 23 Python
python下读取公私钥做加解密实例详解
Mar 29 Python
Python实现统计文本文件字数的方法
May 05 Python
python使用webdriver爬取微信公众号
Aug 31 Python
Python数据可视化库seaborn的使用总结
Jan 15 Python
Python数据类型之Dict字典实例详解
May 07 Python
python爬虫 urllib模块url编码处理详解
Aug 20 Python
Python @property使用方法解析
Sep 17 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
Oct 30 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
Mar 30 Python
使用Python爬取Json数据的示例代码
Dec 07 Python
使用python求解迷宫问题的三种实现方法
Mar 17 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
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
Yii2 rbac权限控制操作步骤实例教程
2016/04/29 PHP
php 解决substr()截取中文字符乱码问题
2016/07/18 PHP
使用正则去除php代码中的注释方法
2016/11/03 PHP
Yii2实现UploadedFile上传文件示例
2017/02/15 PHP
php多进程中的阻塞与非阻塞操作实例分析
2020/03/04 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
在chrome中window.onload事件的一些问题
2010/03/01 Javascript
javascript面向对象之Javascript 继承
2010/05/04 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
2016/08/23 Javascript
Bootstrap CSS布局之图像
2016/12/17 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
js链表操作(实例讲解)
2017/08/29 Javascript
把JavaScript代码改成ES6语法不完全指南(分享)
2017/09/10 Javascript
vue生命周期实例小结
2018/08/15 Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
2019/04/19 Javascript
vue element-ui el-date-picker限制选择时间为当天之前的代码
2019/11/07 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
vue 根据选择的月份动态展示日期对应的星期几
2021/02/06 Vue.js
35个Python编程小技巧
2014/04/01 Python
python的多重继承的理解
2017/08/06 Python
Python + selenium自动化环境搭建的完整步骤
2018/05/19 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
解决python 读取 log日志的编码问题
2019/12/24 Python
tensorflow常用函数API介绍
2020/04/19 Python
Python实现数字的格式化输出
2020/08/01 Python
Python Pivot table透视表使用方法解析
2020/09/11 Python
西班牙国家航空官方网站:Iberia
2017/11/16 全球购物
印度手工编织服装和家居用品商店:Fabindi
2019/10/07 全球购物
贷款担保书范文
2014/05/13 职场文书
群众路线剖析材料范文
2014/10/09 职场文书
2014年财务部工作总结
2014/11/11 职场文书
导游词之山西-五老峰
2019/10/07 职场文书
Python 中面向接口编程
2022/05/20 Python