django-bulk-hooks 0.1.184__py3-none-any.whl → 0.1.185__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-bulk-hooks might be problematic. Click here for more details.
- django_bulk_hooks/queryset.py +39 -6
- {django_bulk_hooks-0.1.184.dist-info → django_bulk_hooks-0.1.185.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.1.184.dist-info → django_bulk_hooks-0.1.185.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.1.184.dist-info → django_bulk_hooks-0.1.185.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.1.184.dist-info → django_bulk_hooks-0.1.185.dist-info}/WHEEL +0 -0
django_bulk_hooks/queryset.py
CHANGED
|
@@ -537,6 +537,19 @@ class HookQuerySet(models.QuerySet):
|
|
|
537
537
|
model_cls = self.model
|
|
538
538
|
inheritance_chain = self._get_inheritance_chain()
|
|
539
539
|
|
|
540
|
+
# Remove custom hook kwargs before passing to Django internals
|
|
541
|
+
django_kwargs = {
|
|
542
|
+
k: v
|
|
543
|
+
for k, v in kwargs.items()
|
|
544
|
+
if k not in ["bypass_hooks", "bypass_validation"]
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
# Safety check to prevent infinite recursion
|
|
548
|
+
if len(inheritance_chain) > 10: # Arbitrary limit to prevent infinite loops
|
|
549
|
+
raise ValueError(
|
|
550
|
+
"Inheritance chain too deep - possible infinite recursion detected"
|
|
551
|
+
)
|
|
552
|
+
|
|
540
553
|
# Group fields by model in the inheritance chain
|
|
541
554
|
field_groups = {}
|
|
542
555
|
for field_name in fields:
|
|
@@ -549,8 +562,28 @@ class HookQuerySet(models.QuerySet):
|
|
|
549
562
|
field_groups[model].append(field_name)
|
|
550
563
|
break
|
|
551
564
|
|
|
552
|
-
#
|
|
565
|
+
# Process in batches
|
|
566
|
+
batch_size = django_kwargs.get("batch_size") or len(objs)
|
|
553
567
|
total_updated = 0
|
|
568
|
+
|
|
569
|
+
with transaction.atomic(using=self.db, savepoint=False):
|
|
570
|
+
for i in range(0, len(objs), batch_size):
|
|
571
|
+
batch = objs[i : i + batch_size]
|
|
572
|
+
batch_result = self._process_mti_bulk_update_batch(
|
|
573
|
+
batch, field_groups, inheritance_chain, **django_kwargs
|
|
574
|
+
)
|
|
575
|
+
total_updated += batch_result
|
|
576
|
+
|
|
577
|
+
return total_updated
|
|
578
|
+
|
|
579
|
+
def _process_mti_bulk_update_batch(self, batch, field_groups, inheritance_chain, **kwargs):
|
|
580
|
+
"""
|
|
581
|
+
Process a single batch of objects for MTI bulk update.
|
|
582
|
+
Updates each table in the inheritance chain for the batch.
|
|
583
|
+
"""
|
|
584
|
+
total_updated = 0
|
|
585
|
+
|
|
586
|
+
# Update each table in the inheritance chain
|
|
554
587
|
for model, model_fields in field_groups.items():
|
|
555
588
|
if not model_fields:
|
|
556
589
|
continue
|
|
@@ -560,7 +593,7 @@ class HookQuerySet(models.QuerySet):
|
|
|
560
593
|
# Child models use the parent link to reference the root PK
|
|
561
594
|
if model == inheritance_chain[0]:
|
|
562
595
|
# Root model - use primary keys directly
|
|
563
|
-
pks = [obj.pk for obj in
|
|
596
|
+
pks = [obj.pk for obj in batch]
|
|
564
597
|
filter_field = 'pk'
|
|
565
598
|
else:
|
|
566
599
|
# Child model - use parent link field
|
|
@@ -575,25 +608,25 @@ class HookQuerySet(models.QuerySet):
|
|
|
575
608
|
continue
|
|
576
609
|
|
|
577
610
|
# Get the parent link values (these should be the same as the root PKs)
|
|
578
|
-
pks = [getattr(obj, parent_link.attname) for obj in
|
|
611
|
+
pks = [getattr(obj, parent_link.attname) for obj in batch]
|
|
579
612
|
filter_field = parent_link.attname
|
|
580
613
|
|
|
581
614
|
if pks:
|
|
582
615
|
base_qs = model._base_manager.using(self.db)
|
|
583
616
|
|
|
584
|
-
# Build CASE statements for each field
|
|
617
|
+
# Build CASE statements for each field to perform a single bulk update
|
|
585
618
|
case_statements = {}
|
|
586
619
|
for field_name in model_fields:
|
|
587
620
|
field = model._meta.get_field(field_name)
|
|
588
621
|
when_statements = []
|
|
589
622
|
|
|
590
|
-
for pk, obj in zip(pks,
|
|
623
|
+
for pk, obj in zip(pks, batch):
|
|
591
624
|
value = getattr(obj, field_name)
|
|
592
625
|
when_statements.append(When(**{filter_field: pk}, then=Value(value, output_field=field)))
|
|
593
626
|
|
|
594
627
|
case_statements[field_name] = Case(*when_statements, output_field=field)
|
|
595
628
|
|
|
596
|
-
# Execute
|
|
629
|
+
# Execute a single bulk update for all objects in this model
|
|
597
630
|
updated_count = base_qs.filter(**{f"{filter_field}__in": pks}).update(**case_statements)
|
|
598
631
|
total_updated += updated_count
|
|
599
632
|
|
|
@@ -9,9 +9,9 @@ django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,
|
|
|
9
9
|
django_bulk_hooks/manager.py,sha256=KLEjpQRt4WlzgBAf_X3XOAPUQM8Jmc1fIt8yr62FPQc,3044
|
|
10
10
|
django_bulk_hooks/models.py,sha256=7fnx5xd4HWXfLVlFhhiRzR92JRWFEuxgk6aSWLEsyJg,3996
|
|
11
11
|
django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
|
|
12
|
-
django_bulk_hooks/queryset.py,sha256=
|
|
12
|
+
django_bulk_hooks/queryset.py,sha256=9ME8FNy_DdF6As-q1mb81u7agzfMR2rNGz6NlVB5bRI,26976
|
|
13
13
|
django_bulk_hooks/registry.py,sha256=-mQBizJ06nz_tajZBinViKx_uP2Tbc1tIpTEMv7lwKA,705
|
|
14
|
-
django_bulk_hooks-0.1.
|
|
15
|
-
django_bulk_hooks-0.1.
|
|
16
|
-
django_bulk_hooks-0.1.
|
|
17
|
-
django_bulk_hooks-0.1.
|
|
14
|
+
django_bulk_hooks-0.1.185.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.185.dist-info/METADATA,sha256=KO4qnnw3JdSvWDFUiXipL5SIHPKm79HufxSJBNqgDTk,6951
|
|
16
|
+
django_bulk_hooks-0.1.185.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
17
|
+
django_bulk_hooks-0.1.185.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|