Update multiple objects at once in Django?

前端 未结 2 409
耶瑟儿~
耶瑟儿~ 2020-12-25 13:07

I am using Django 1.9. I have a Django table that represents the value of a particular measure, by organisation by month, with raw values and percentiles:

cl         


        
相关标签:
2条回答
  • 2020-12-25 13:15

    Atomic transactions can reduce the time spent in the loop:

    from django.db import transaction
    
    with transaction.atomic():
        for i, row in df.iterrows():
            mv = MeasureValue.objects.get(org=row.org, month=month)
    
            if (row.percentile is None) or np.isnan(row.percentile): 
                # if it's already None, why set it to None?
                row.percentile = None
    
            mv.percentile = row.percentile
            mv.save()
    

    Django’s default behavior is to run in autocommit mode. Each query is immediately committed to the database, unless a transaction is actives.

    By using with transaction.atomic() all the inserts are grouped into a single transaction. The time needed to commit the transaction is amortized over all the enclosed insert statements and so the time per insert statement is greatly reduced.

    0 讨论(0)
  • 2020-12-25 13:31

    As of Django 2.2, you can use the bulk_update() queryset method to efficiently update the given fields on the provided model instances, generally with one query:

    objs = [
        Entry.objects.create(headline='Entry 1'),
        Entry.objects.create(headline='Entry 2'),
    ]
    objs[0].headline = 'This is entry 1'
    objs[1].headline = 'This is entry 2'
    Entry.objects.bulk_update(objs, ['headline'])
    

    In older versions of Django you could use update() with Case/When, e.g.:

    from django.db.models import Case, When
    
    Entry.objects.filter(
        pk__in=headlines  # `headlines` is a pk -> headline mapping
    ).update(
        headline=Case(*[When(pk=entry_pk, then=headline)
                        for entry_pk, headline in headlines.items()]))
    
    0 讨论(0)
提交回复
热议问题