Reputation: 4983
For example, a table with columns of acct
, ip
, status
, (acct
is unique), there's about 1000 rows need to be updated to a specific ip
and status
(e.g. 11.11.11.11 and great), I noticed update
seems to be a good choice: Entry.objects.filter(acct=xxx).update(comments_on=False)
, but these 1000 rows all come with different acct
, and iterating would cost too much overhead(actually there're at least 100k rows need to be updated at a time), what's a proper way to do this?
Upvotes: 0
Views: 1059
Reputation: 45595
I am afraid that using filter().update()
is the only way to do it.
To increase the speed of mass operation I suggest you to wrap this bulk update into transaction:
from django.db import transaction
with transaction.atomic():
for acct, ip, status in accounts_to_update:
Entry.objects.filter(acct=acct).update(ip=ip, status=status)
UPDATE: @jessamyn-smith's idea is brilliant! acct
is unique but how about ip
/status
pair? If you regroup source list by this pair will it reduce number of queries?
accounts_to_update = [
('xxx', '1.2.3.4', 'great'),
('xxy', '1.2.3.4', 'fail'),
('xxz', '1.2.3.4', 'great'),
('xx0', '1.2.3.0', 'great'),
]
ip_status_dict = {}
for acct, ip, status in accounts_to_update:
accounts = ip_status_dict.setdefault((ip, status), [])
accounts.append(acct)
with transaction.atomic():
for (ip, status), accounts in ip_status_dict.iteritems():
Entry.objects.filter(acct__in=accounts).update(ip=ip, status=status)
Upvotes: 0
Reputation: 1649
You can filter on any attributes, so if it's possible to write a query that describes the set of objects to update, you can use update.
Entry.objects.filter(attr1=yyy, attr2=zzz).update('11.11.11.11', 'great')
If what you have is a list of ids, you could do the following, though I don't guarantee it'll give you the performance you want:
Entry.objects.filter(acct__in=<list_of_accounts>).update('11.11.11.11', 'great')
Upvotes: 3