Django如何基于另一张表批量更新Table2数据?
用bulk_update批量更新Table2数据(基于Table1的hash_str匹配)
我有两张包含相同hash_str字段的Django模型表Table1和Table2,结构定义如下:
from django.db import models class Table1(models.Model): data = models.JSONField(...) hash_str = models.CharField(...) class Table2(models.Model): name = models.CharField(...) parsed = models.DateTimeField(...) hash_str = models.CharField(...) is_updated = models.BooleanField(...)
原来逐个更新的写法在数据量大时效率极低:
# 低效的逐个更新方式 for t2_obj in Table2.objects.filter(is_updated=False): t1_obj = Table1.objects.get(hash_str=t2_obj.hash_str) t2_obj.name = t1_obj.data["name"] t2_obj.parsed = t1_obj.data["parsed"] t2_obj.is_updated = True t2_obj.save()
优化方案:用bulk_update批量处理
核心思路是减少数据库交互次数,先批量获取待更新对象和对应数据,再一次性批量写入:
# 1. 批量获取所有需要更新的Table2对象 t2_objs = list(Table2.objects.filter(is_updated=False)) # 2. 提取hash_str列表,批量查询Table1并构建映射字典(避免循环查库) hash_list = [t2.hash_str for t2 in t2_objs] t1_map = {t1.hash_str: t1 for t1 in Table1.objects.filter(hash_str__in=hash_list)} # 3. 遍历更新Table2对象字段 updated_objs = [] for t2 in t2_objs: t1 = t1_map.get(t2.hash_str) if not t1: # 可选:处理Table1无对应hash_str的情况,比如跳过或标记 continue t2.name = t1.data["name"] t2.parsed = t1.data["parsed"] t2.is_updated = True updated_objs.append(t2) # 4. 执行批量更新,指定要更新的字段 if updated_objs: Table2.objects.bulk_update(updated_objs, ["name", "parsed", "is_updated"])
关键注意事项
bulk_update必须明确指定要更新的字段列表,只有列表内的字段会被写入数据库- 若数据量极大(如上万条),建议分批次处理避免内存溢出:
from itertools import islice batch_size = 1000 while updated_objs: batch = list(islice(updated_objs, batch_size)) Table2.objects.bulk_update(batch, ["name", "parsed", "is_updated"]) updated_objs = updated_objs[batch_size:] - 要提前考虑Table1中无对应
hash_str的场景,根据业务需求做跳过、日志记录或状态标记
内容的提问来源于stack exchange,提问作者lyova24
相关产品推荐
相关产品推荐

