django的QuerySet合并及缺陷分析

本文探讨了在Django中合并QuerySet时遇到的问题,特别是使用a|b合并操作和chain函数的情况。方式1(a|b)可能导致因并发或异步操作引起的错误数据合并,而方式2(chain)虽然避免了该问题,但返回的迭代器仅可遍历一次。为解决这个问题,建议使用chain转换为列表进行数据合并,确保数据一致性。同时,这种方式对原始代码的影响较小。
摘要由CSDN通过智能技术生成

使用场景:

django查询数据库得到QuerySet A,对QuerySet A进行区分处理,并save保存;再查询另一条件得到QuerySet B,对QuerySet B进行区分处理,并save保存,最后想对QuerySet A 和QuerySet B合并,用于之后的统一处理操作。

常见的合并处理方式

a|b 或 chain函数

方式1
querysets = queryset_a | queryset_b

方式2
from itertools import chain
querysets = chain(queryset_a, queryset_b)

缺陷说明:

方式1
本着两个QuerySet合并,最终还想得到一个完整的大QuerySet,开始选择了a|b的形式,但是发现这种形式在当前场景存在问题。
a|b合并的思想类似于:
    查询a时使用的sql语句 和 查询b时使用的sql语句 进行联合查询。如果上面查询到QuerySet a和b后,对a和b进行操作,并a.save(),b.save()保存,恰巧修改的字段为sql语句中的查询字段,那么a|b合并时,默认会使用之前a和b的sql语句联合查询,但是此时a和b已经通过.save进行字段修改了,那么查询出来的集合就为空,获取不对原始的结果了;如果在这个过程中,又创建了新的数据,并且新数据还满足上面的sql语句,那么查询结果可能为新增加的数据,并非原始的期望数据,出现问题。
所以: 对于较大的服务器,服务往往是并发或异步的,这样使用a|b进行数据合并,不论是自己save保持修改数据,还是并发创建新数据,合并的结果往往是错误的。需要慎重使用!

方式2
使用chain函数得到的是迭代器,querysets = chain(queryset_a, queryset_b),因为是迭代器,对于querysets只能遍历使用1次,之后不会再有数据,可以使用list(querysets)进行转换,列表可以多次使用;但是还是没有得到最初期望的
QuerySet格式,最多set(list(querysets))得到个集合,没有太多意义。

总结:

最后使用chain进行数据合并,再通过list转化成列表,对于原始代码没有什么影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值