Django笔记十三之select_for_update等选择和更新等相关操作

本篇笔记将介绍 update 和 create 的一些其他用法,目录如下:

  1. get_or_create
  2. update_or_create
  3. select_for_update
  4. bulk_create
  5. bulk_update

1、get_or_create

前面我们介绍过 get() 和 create() 的用法,那么 get_or_create() 的意思很简单,就是 获取或者创建,如果 存在就返回,不存在就先创建再返回

假设对于 Blog model,我们想看下数据库有没有 name=”hunter”, tagline=”tagline_test” 的数据,没有的话创建并获取这条数据,有的话,就直接获取。

在之前我们操作可能是:

try:
    blog = Blog.objects.get(name='hunter', tagline='tagline_test')
except Blog.DoesNotExist:
    blog = Blog(name='hunter', tagline='tagline_test')
    blog.save()

现在我们可以直接这样操作:

blog, created = Blog.objects.get_or_create(name='hunter', tagline='tagline_test')

这个函数的返回值有两个,一个是操作的 model 实例,一个是是否是 created 的 布尔型数据。

created 为 True,表示这条数据是创建,create() 到的
created 为 False,表示这条数据是获取, get() 到的

注意: 查询的条件必须是 唯一的,否则会造成多条数据返回而报错,这个逻辑同 get() 函数。

注意: 使用的字段,没有唯一的约束,并发的调用这个方法可能会导致多条相同的值插入。

字段默认值

假设 Blog 这个 model 除了 name, tagline 这两个字段外,还有 field_1 和 field_2 字段,但是他们不在我们查询的条件内,作用为在创建的时候设置的默认值,我们可以通过 defaults 来操作:

blog, created = Blog.objects.get_or_create(
    name='hunter',
    tagline='tagline_test',
    defaults={
        'field_1': 'field_1_value',
        'field_2': 'field_2_value'
    }
)

最后关于这个函数,有个小提示,如果这个函数用在接口里,那么根据 幂等性,我们应该使用 POST 方法来请求,而不是 GET 请求。

关于幂等性的概念,有兴趣的话可以去查询一下。

2、update_or_create

更新或者创建,使用方法同 get_or_create()

假设对于 Blog model 我们想实现的操作如果存在 name=’hunter’, tagline=’tagline_test’ 的数据就将其 field_1 和 field_2 的字段更新,不存在的话,就创建该数据。

之前的操作逻辑大概如下:

defaults = {"field_1": "field_1_value", "field_2": "field_2_value"}

try:
    obj = Blog.objects.get(name='hunter', tagline='tagline_test')
    for key, value in defaults.items():
        setattr(obj, key, value)
    obj.save()
except:
    new_values = {"name": "hunter", "tagline": "tagline_test}
    new_values.update(defaults)
    obj = Blog(**new_values)
    obj.save()

现在我们使用 update_or_create 可以如下操作:

obj, created = Blog.objects.update_or_create(
    name='hunter', tagline='tagline_test',
    defaults={"field_1": "field_1_value", "field_2": "field_2_value"}
)

3、select_for_update

select_for_update 的操作复杂一点,作用类似于 SQL 中的 SELECT … FOR UPDATE 语句

操作如下:

from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
    for blog in blog_list:
        ...

当 blog_list 去获取数据的时候,所有匹配上的 entries 都会被锁,直到这个事务结束。

意味着这个时候,其他的事务会被阻止更改或者重新在这些数据上加锁。

我们来举个例子,在我们执行下面的语句时:

import time
from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
    for blog in blog_list:
        print("locking ...")
        time.sleep(20)

这个时候,我们在重新开一个 shell,来执行下面的语句:

Blog.objects.filter(name="hunter").update(name="hunter_1")

因为第一个 shell 里执行的命令还没有结束,而且在数据上加了锁,因此第二个 shell 里的语句会进入等待,直到第一个 shell 里的命令执行完成之后,第二个 shell 里的命令才会执行。

注意: 如果在第一个命令里,对 blog 数据进行操作,比如 把 name 字段改为了 hunter_2,那么在第二条命令的条件里筛选不到结果然后更新的。

4、bulk_create

批量创建,在前面介绍增删改查的时候介绍过一次,这里再简单做一下示例:

from blog.models import Blog

blog_list = [
    Blog(name="hunter_1", tagline="tag_1"),
    Blog(name="hunter_2", tagline="tag_2"),
    Blog(name="hunter_3", tagline="tag_3"),
    Blog(name="hunter_4", tagline="tag_4")
]

Blog.objects.bulk_create(blog_list)

如果我们批量创建的数量过多,我们可以指定分批次来创建,通过 batch_size 参数来指定。

Blog.objects.bulk_create(blog_list, batch_size=2)

5、bulk_update

批量更新,方式与 bulk_create 的方式类似,以下是使用示例:

blog_list = Blog.objects.filter(id__lte=20)

for blog in blog_list:
    blog.name = "name_updated"
    blog.tagline = "tag_updated"

Blog.objects.bulk_update(blog_list, fields=['name'], batch_size=2)

需要注意的是 bulk_update 多了个参数,fields 这个是用来指定需要更新的字段。

如我们上面的命令所示,我们指定更新的是 name 字段,那么就算我们更改了 tagline 的数据,只要 fields 列表里没有指定该字段,那么后台也不会更新该字段。

以上就是本篇笔记全部内容,接下来我们将介绍一下查询中的其他用法,比如latest,first,contains 等。

本文首发于本人微信公众号,可搜索关注:Django笔记。
如果想获取更多相关文章,可扫码关注阅读:

Django笔记十三之select_for_update等选择和更新等相关操作

Original: https://blog.csdn.net/weixin_43354181/article/details/123697817
Author: vv安的浅唱
Title: Django笔记十三之select_for_update等选择和更新等相关操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/735008/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • python not found in axis_fbprophet报错:KeyError: ‘[] not found in axis’

    近日在尝试使用fbprophet算法替换原来的ARIMA做时序预测,安装过程中踩过的坑先不提(后面有时间会另起一篇说明),此处单说一个很莫名其妙的问题。 在跑官方示例的时候: im…

    Python 2023年8月19日
    057
  • Django设置Pymysql数据库

    1.mysql配置1.安装pymysqlpip3 install pymysql2.在项目下__init__文件输入:import pymysqlpymysql.install_a…

    Python 2023年8月4日
    036
  • PyQt5 小工具:Excel数据分组汇总器…

    在写数据汇总分组工具之前梳理一下需求,要求一:能够将excel的数据展示到列表中。要求二:能够支持按列汇总数据,并且多列分组汇总。要求三:能够预览分组汇总以后的数据,最后将分好组汇…

    Python 2023年5月24日
    0115
  • Numpy数组与矩阵(二)

    Numpy数组与矩阵(二) Numpy数组与矩阵(二) * 1 数组操作 – 1.1 修改数组形状 1.3 修改数组维度 1.4 连接两个数组 1.5 分割数组 1.6…

    Python 2023年8月25日
    067
  • 用python写搜索引擎_用Python打造属于自己的搜索引擎

    写在前面 昨天接了一个IT行业培训广告,有极小部分读者取关了,虽然体量很小,但我还是有点痛心! 经常熬夜更新公众号,累积收到的打赏连一杯咖啡都买不了。现在发个广告赚个小小的咖啡钱就…

    Python 2023年8月14日
    043
  • 基于【MUI+Flask+MongoDB+HBuilderX】登录模块完善篇

    ### 回答1: MUI Echarts是一个基于Vue.js和ECharts的移动端图表组件库。 MUI Echarts提供了丰富的图表类型,包括折线图、柱状图、饼图、雷达图等。…

    Python 2023年8月12日
    091
  • Pytest参数

    参数:pytest -v 说明:可以输出用例更加详细的执行信息,比如用例所在的文件及用例名称等pytest -s 说明:输入我们用例中的调式信息,比如print的打印信息等pyte…

    Python 2023年9月12日
    055
  • 一文叫你搞懂乐鑫物联网ESP芯片及开发

    ESP8266开发 ESP8266的核心SDK主要分为ESP NonOS SDK 和 ESP RTOS SDK,顾名思义,一个是没有系统的SDK,一个是基于FREE RTOS系统的…

    Python 2023年6月3日
    079
  • GPS定位原理

    GPS卫星: 卫星定位系统是一种使用卫星对某物进行准确定位的技术,它从最初的定位精度低、不能实时定位、难以提供及时的导航服务,发展到现如今的高精度GPS全球定位系统,实现了在任意时…

    Python 2023年10月27日
    044
  • 刨析Django—-问题汇总

    hostname, aliases, ipaddrs = gethostbyaddr(name) UnicodeDecodeError: ‘utf-8’ c…

    Python 2023年8月6日
    033
  • 【笔记】Pycharm画图

    先调用导入2个基本模块 from numpy import * from matplotlib import pyplot as plt import matplotlib.pyp…

    Python 2023年8月31日
    079
  • Linux笔记

    一。基础思想 一切皆文件。 两条权限原则: 权限分组原则 权限最小原则 su是切换用户,而sudo则是用root权限执行某操作( 普通用户+sudo=安全) Linux目录 系统只…

    Python 2023年9月28日
    034
  • Spark中资源调度和任务调度

    Spark比MR快的原因 1、Spark基于内存的计算 2、粗粒度资源调度 3、DAG有向无环图:可以根据宽窄依赖划分出可以并行计算的task 细粒度资源调度 MR是属于细粒度资源…

    Python 2023年6月3日
    061
  • 四、pytest框架

    一. Pytest-基本使用 应用场景:pytest 框架可以解决我们多个测试脚本一起执行的问题 1.1 安装和介绍 概念:pytest 是 python 的一种单元测试框架,同自…

    Python 2023年9月12日
    064
  • 『Python核心技术与实战』pandas.DataFrame()函数介绍

    pandas.DataFrame()函数介绍! 文章目录 一. 创建DataFrame * 1.1. numpy创建 1.2. 直接创建 1.3. 字典创建 1.4. Series…

    Python 2023年8月7日
    055
  • 周赛328总结

    周赛328总结 第三题思路正确,但是但是卡在了返回结果用了int变量…很是无语二维前缀和二维差分get 数组元素和与数字和的绝对差【LC2535】 给你一个正整数数组 …

    Python 2023年11月5日
    038
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球