Backend - Django ORM 性能优化(Update 更新/修改)

目录

一、批量更新(bulk_update)

用法:

二、update   vs   save

(一)用法

 (二)注意

1. update:更新多笔数据

2. save:更新一笔数据

3. 最好传入 update_fields 参数

        例如:

        原因:

(三)執行效率

三、update   vs   save   vs   bulk_update

(一)对比

(二)更新主表的外键栏位值

(三)获取 update 前、后的数据

1. 影响

2. 怎样保持update之前的数据不会更变呢?

解决办法:结合列表生成式。


ORM (Object Relational Mapping)
含义:物件导向(面向对象)
实际理解:代码里的model对应pgadmin的table

Django CRUD 四大事务:增 create   删 delete   改 update   查 read

一、批量更新(bulk_update)

一旦使用到queryset的update和create時,一定要注意是不是批量执行。 

例子:更新书籍封面颜色coverColor

下面是models的设定

# 主表Book的model
class Book(models.Model):
    authorid = models.ForeignKey(Author, related_name="authorId", on_delete=models.CASCADE, limit_choices_to={"active": True}, verbose_name=_("authorName"))
    booktype = models.CharField(verbose_name=_("BookType"), max_length=40)
    coverColor = models.CharField(verbose_name=_("Cover"), max_length=40)
    fontColor = models.CharField(verbose_name=_("Font"), max_length=40)
 
# 外键表Author的model
class Author(models.Model):
    name = models.CharField(verbose_name=_("authorName"), max_length=40)
    age = models.IntegerField(default=0)
用法:
# 第一种:
bookqry = models.Book.objects.filter(coverColor__in=['red', 'blue'])
	for c in bookqry:
	    c.fontColor = 'red'
	    c.coverColor= 'purple'
models.Book.objects.bulk_update(bookqry, ['fontColor ', 'coverColor'])

# 第二种:
booklist = ['数据结构1', '数据结构2']
book_price = {'数据结构1':['60', '清北社1'], '数据结构2':['70', '清北社2'], }
def __bulk_update_book(self, booklist, book_price, lastevent):
        book_qst = models.Book.objects.filter(bookname__in=booklist)
        new_list = list()
        for b in book_qst:
            b.price = i.price + int(book_price[i.bookname][0])
            b.place = int(book_price[i.price][1])
            b.lastevent = lastevent
            new_list.append(b)
        models.Book.objects.bulk_update(new_list, ['price ', 'place', 'lastevent'], batch_size=1000)  
# 其中,batch_size作用于数据量大的情况下

二、update   vs   save

(一)用法

update是批量更新数据库,而save是单个执行更新。

        book_objs.update(fontColor='red')

       book_obj.fontColor = 'red'

       book_obj.save()

        其中:book_objs = models.Book.objects.filter(coverColor='red')是批量的books, 

                   book_obj = models.Book.objects.filter(coverColor='red').first()是单个的book

 (二)注意

1. update:更新多笔数据

        给所有book的fontColor,賦值'red'。

2. save:更新一笔数据

        只更新一個book。 

3. 最好传入 update_fields 参数

        只控制需更新的字段(其他字段保持原状)。

        例如:
book_obj.fontColor = 'red'
book_obj.save(update_fields=[" fontColor "])
        原因:

        针对多线程更新同个表时,若每个线程save不同的栏位值,最终,只会保留最后一个执行的多线程save的栏位值(相当于之前的线程save的值会被覆盖掉)

(三)執行效率

        从SQL的执行上看,update优于save方式。

        从使用上看,update适用于批量数据更新,而save只适合做单条记录的数据更新操作。

        update能返回更新的记录条数,save没有返回值。

三、update   vs   save   vs   bulk_update

(一)对比

1.save 适用于单笔数据更新(前提是只能获取一笔数据,queryset可以加first,也可以不加first,但前提是记录只存在一笔)

2.update 适用于更新多笔数据,相同栏位赋予相同的值(进行相同赋值的批量更新)

3.bulk_update 适用于更新多笔数据,相同的栏位不同的值(也就是更新多个对象)

4.注意:update一定不能结合.first(),但是update可以结合.get(当只有一笔数据时)

(二)更新主表的外键栏位值

# 需要先在外键表查询,得到authorqry的Object查询集
authorqry = models.Author.objects.filter(name='萝卜干').first()
# 将外键的查询集放入到主表,作查询条件
models.Book.objects.filter(authorid=authorqry).update(
       fontColor='red',
       coverColor='purple',
)

(三)获取 update 前、后的数据

1. 影响

update 的数据,会在 update 后被更新。

(即,最新数据,使用了copy.deepcopy 深拷贝也无效)

2. 怎样保持update之前的数据不会更变呢?

解决办法:结合列表生成式
get_qst = models.book.objects.all()
deep_old_data = [i for i in get_qst] # 深拷贝 (列表生成式)
new_old_data = get_qst.update(desc='测试')

# deep_old_data 表示旧数据(不会被update操作所改变)
# new_old_data 表示更新的笔数(是int类型)

update 后的queryset数据,仅仅表示更新的笔数(int类型)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值