1212class UserEventQuerySet (QuerySet ):
1313 def decay (self ):
1414 from collections import defaultdict
15-
1615 from django .db import transaction
17-
1816 objects = (
1917 self .exclude (decay_progression = DecayProgressionEnum .FIXED .value )
2018 .exclude (next_decay__isnull = True )
@@ -29,22 +27,17 @@ def decay(self):
2927 objects = objects .select_related ("data_model" )
3028 else :
3129 objects = objects .prefetch_related ("data_model" )
32-
3330 # Load into memory so we can mutate fields and bulk-write back.
3431 events = list (objects )
3532 if not events :
3633 return 0
37-
3834 # Group by concrete class since bulk_update works per-table.
3935 data_models_by_class = defaultdict (list )
40-
4136 for obj in events :
4237 obj .decay_times += 1
4338 data_model = obj .data_model
44-
4539 if data_model is not None :
4640 data_model .reliability -= 1
47-
4841 if data_model is None or data_model .reliability == 0 :
4942 obj .next_decay = None
5043 else :
@@ -54,17 +47,15 @@ def decay(self):
5447 obj .next_decay += datetime .timedelta (
5548 days = obj .decay_timedelta_days ** (obj .decay_times + 1 )
5649 )
57-
5850 if data_model is not None :
5951 data_models_by_class [data_model .__class__ ].append (data_model )
60-
6152 # Bulk-write instead of per-object .save() to avoid O(N) queries.
6253 # Atomic so partial failures don't leave inconsistent state.
6354 with transaction .atomic ():
6455 for model_class , models_list in data_models_by_class .items ():
65- model_class . objects . bulk_update ( models_list , [ "reliability" ] )
66- self . model . objects .bulk_update (events , ["decay_times" , "next_decay" ] )
67-
56+ unique_models = { m . pk : m for m in models_list }. values ( )
57+ model_class . objects .bulk_update (unique_models , ["reliability" ], batch_size = 1000 )
58+ self . model . objects . bulk_update ( events , [ "decay_times" , "next_decay" ], batch_size = 1000 )
6859 return len (events )
6960
7061 def visible_for_user (self , user ):
0 commit comments