如何避免Django查询在循环中自动更新,获取数据库原始数据?
解决Django循环中查询自动包含新增数据的问题
问题原因
Django的QuerySet是惰性执行的,并且每次调用exists()、filter()这类方法时,都会重新向数据库发起查询请求。你代码里每次循环时执行的q.exists(),都会实时查询当前数据库的状态,自然会包含刚新增的记录,导致本该创建的条目被误判为已存在。
解决方案
提前把原始数据库中所有需要判断的记录特征提取出来,存入一个静态集合,后续循环时直接在这个集合里做判断,不再每次查询数据库。这样集合里始终只有程序启动时的原始数据,不会被新增记录影响。
修改后的代码示例:
# 提前一次性获取原始数据库中所有记录的字段组合,存入集合(查询仅执行一次) existing_records = set( Movimentacao.objects.values_list( 'entrada_saida', 'data', 'movimentacao', 'produto', 'instituicao', 'quantidade', 'preco_unitario', 'valor_da_operacao' ) ) counter = 0 for m in movimentacoes: # 将当前待处理的条目转换成和集合中一致的元组格式 current_tuple = (m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7]) if current_tuple not in existing_records: # 仅当原始数据库中不存在时才创建新记录 line = Movimentacao( entrada_saida=m[0], data=m[1], movimentacao=m[2], produto=m[3], instituicao=m[4], quantidade=m[5], preco_unitario=m[6], valor_da_operacao=m[7] ) counter += 1 line.save()
补充说明
- 用
values_list配合set是因为集合的成员判断效率极高(O(1)),如果数据量很大,比每次查数据库或者遍历列表要快得多。 - 如果你不需要后续用到新增的记录,完全不用更新这个
existing_records集合,它会一直保持原始数据库的状态。
内容的提问来源于stack exchange,提问作者Felipe Dourado
相关产品推荐
相关产品推荐

