如何高效批量更新多个字段值各不相同的Django模型对象
优化方案
方案1:Excel批量读取 + Django bulk_update(最适配当前场景)
这是bulk_update针对你业务的正确适配方式,核心逻辑是一次性读取Excel全量数据、一次性查出所有待更新对象、匹配赋值后批量提交,183场比赛仅需2次数据库交互(1次查询+1次更新),全程耗时不超过1秒。
首先安装读取Excel的依赖:pip install pandas openpyxl
完整代码示例:
import pandas as pd from .models import NCAABGame # 1. 读取Excel统计数据 df = pd.read_excel("你的统计数据文件存储路径.xlsx") # 2. 一次性查出所有待更新的比赛,转成{球队名: 比赛对象}的字典方便快速匹配 to_update_map = { game.name.name: game for game in NCAABGame.objects.filter(updated=False).only( "id", "name", "field_goals", "field_goal_attempts", "three_points", "three_point_attempts", "updated" # 此处补充所有需要更新的字段,减少查询字段可提升速度 ) } update_list = [] for _, row in df.iterrows(): team_name = row["Excel里球队名列的列名"] if team_name not in to_update_map: continue # 未匹配到的球队可以自行加日志记录排查 game = to_update_map[team_name] # 逐字段赋值 game.field_goals = row["Excel里field_goals列的列名"] game.field_goal_attempts = row["Excel里field_goal_attempts列的列名"] game.three_points = row["Excel里three_points列的列名"] game.three_point_attempts = row["Excel里three_point_attempts列的列名"] game.updated = True update_list.append(game) # 批量提交更新,单次SQL完成所有操作 NCAABGame.objects.bulk_update( update_list, fields=["field_goals", "field_goal_attempts", "three_points", "three_point_attempts", "updated"], batch_size=100 # 峰值183场分两批提交即可,也可以不设置默认全量提交 )
操作流程仅需两步:每日导出Excel覆盖固定路径文件、运行一次脚本即可完成全量更新,无需再逐行复制更新语句。
方案2:无第三方依赖的CSV适配方案
如果不想引入pandas,可以将Excel另存为CSV格式,用Python标准库csv读取数据,后续匹配、批量更新逻辑和方案1完全一致。
方案3:数据库层直接批量更新(性能最高)
如果不想查询待更新对象回应用服务器,可以用Django的Case-When语法直接在数据库层完成条件更新,仅需1次数据库交互,适合数据量较小、字段较少的场景,示例代码:
from django.db.models import Case, When, Value, F NCAABGame.objects.filter(updated=False).update( field_goals=Case( When(name__name='San Francisco', then=Value(38)), When(name__name='其他球队名', then=Value(对应数值)), default=F('field_goals') ), field_goal_attempts=Case( When(name__name='San Francisco', then=Value(55)), When(name__name='其他球队名', then=Value(对应数值)), default=F('field_goal_attempts') ), # 补充其他字段的更新规则 updated=True )
长期优化建议
后续如果能拿到统计数据的API接口,可以把整个流程封装成定时任务,自动拉取统计数据、自动匹配更新,彻底省去人工导出Excel、运行脚本的操作。
内容的提问来源于stack exchange,提问作者Ryan Thomas
相关产品推荐
相关产品推荐

