如何在Django中批量更新JSON字段的指定键值对
在Django中批量更新JSON字段的指定键值
方法一:使用bulk_update(内存修改后批量保存)
这种方式贴合你提到的思路,先查询目标对象,在内存中修改JSON字段的指定键,再批量提交保存,逻辑直观,适合数据量不大的场景。
# 处理Variant模型 variants = list(master_models.Variant.objects.filter( trust_markers__contains={trust_marker_type: True} )) for variant in variants: variant.trust_markers[trust_marker_type] = False master_models.Variant.objects.bulk_update(variants, ['trust_markers']) # 处理Model模型(注意:Model是Django内置类名,建议重命名你的自定义模型避免冲突) target_models = list(master_models.Model.objects.filter( trust_markers__contains={trust_marker_type: True} )) for mdl in target_models: mdl.trust_markers[trust_marker_type] = False master_models.Model.objects.bulk_update(target_models, ['trust_markers'])
提示:将查询集转为
list()是为了避免Django惰性查询导致的重复数据库访问,确保仅查询一次。
方法二:数据库层面直接更新(高效处理大数据量)
如果目标数据量较大,加载所有对象到内存会占用过多资源,可利用数据库的JSON函数直接在库内修改指定键,无需加载对象。
针对PostgreSQL(支持JSONB字段)
Django内置KeyTransform可直接操作JSON键:
from django.db.models import Value from django.db.models.fields.json import KeyTransform # 更新Variant模型 master_models.Variant.objects.filter( trust_markers__contains={trust_marker_type: True} ).update( trust_markers=KeyTransform(trust_marker_type, 'trust_markers').set(Value(False)) ) # 更新Model模型 master_models.Model.objects.filter( trust_markers__contains={trust_marker_type: True} ).update( trust_markers=KeyTransform(trust_marker_type, 'trust_markers').set(Value(False)) )
针对MySQL(支持JSON字段)
自定义JSON_SET函数实现(Django 3.1+支持):
from django.db.models import Func, Value class JSONSet(Func): function = 'JSON_SET' template = "%(function)s(%(expressions)s)" # 更新Variant模型 master_models.Variant.objects.filter( trust_markers__contains={trust_marker_type: True} ).update( trust_markers=JSONSet( 'trust_markers', Value(f'$.{trust_marker_type}'), Value(False) ) ) # 更新Model模型同理 master_models.Model.objects.filter( trust_markers__contains={trust_marker_type: True} ).update( trust_markers=JSONSet( 'trust_markers', Value(f'$.{trust_marker_type}'), Value(False) ) )
方法对比
bulk_update:逻辑简单易调试,适合小数据量;但需加载所有对象到内存,数据量大时资源占用高。- 数据库JSON函数:直接在库内操作,性能更优,适合大数据量;需根据使用的数据库类型选择对应写法。
内容的提问来源于stack exchange,提问作者Ayush Kumar
相关产品推荐
相关产品推荐

