如何强制 django 立即保存而不是在循环后进行批量更新

Posted

技术标签:

【中文标题】如何强制 django 立即保存而不是在循环后进行批量更新【英文标题】:How to force django to save immediately instead of doing a batch update after loop 【发布时间】:2013-12-14 22:58:30 【问题描述】:

我有这个 django views.py 方法,旨在将许多数据插入数据库。它循环遍历模型数组,如果对象尚未在数据库中,则将其插入。

这就是代码的样子:

def update_my_db(request):

    a_models = A_Model.objects.filter(my_flag=True)

    for a_model in a_models:

        b_model_array = []

        [...] # this is where b_model_array gets filled

        for index in range(len(b_model_array)):

            current_b_model = b_model_array[index]

            try:
                b_model = B_Model.objects.get(my_field=current_b_model.my_field)
            except (KeyError, B_Model.DoesNotExist):
                b_model = B_Model.objects.create(field_1=current_b_model.field_1, field_2=current_b_model.field_2)
                b_model.save()

    return HttpResponse(response)

经过几次测试,我注意到 db 仅在最后一次迭代结束时更新,好像 django 等待对 mysql 进行批量插入。

问题是:任何迭代都有可能引发异常,导致迄今为止收集的所有数据由于错误而被丢弃(已经测试并确认)。当涉及到添加 400 行时,在循环 #399 处引发异常并丢弃所有之前的 398 行对我来说是非常不可取的。

我知道批处理是性能方面的最佳选择,但这是一个后台例程,所以我并不担心。

底线:有没有办法真正强制 django 在每次迭代时更新数据库?

【问题讨论】:

【参考方案1】:

如果您使用的是 Django 1.6,请查看:https://docs.djangoproject.com/en/dev/topics/db/transactions/

您对该页面的上下文管理器部分感兴趣:

from django.db import transaction

def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff()

    with transaction.atomic():
        # This code executes inside a transaction.
        do_more_stuff()

【讨论】:

以上是关于如何强制 django 立即保存而不是在循环后进行批量更新的主要内容,如果未能解决你的问题,请参考以下文章

在 .net 核心中,在用户登录后立即进行一些日志记录。而不是在每个请求上

使用ajax将它们作为json后如何循环遍历django表单错误

Django - 从一系列表单中抓取数据并立即保存它们

强制浏览器下载视频,而不是在 html 中打开 [重复]

我怎样才能让我的程序等待输入,而不是在循环中

c#每200个循环后保存Streamwriter而不关闭