django-bulk-hooks 0.1.251__py3-none-any.whl → 0.1.252__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 +132 -5
- {django_bulk_hooks-0.1.251.dist-info → django_bulk_hooks-0.1.252.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.1.251.dist-info → django_bulk_hooks-0.1.252.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.1.251.dist-info → django_bulk_hooks-0.1.252.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.1.251.dist-info → django_bulk_hooks-0.1.252.dist-info}/WHEEL +0 -0
django_bulk_hooks/queryset.py
CHANGED
|
@@ -520,9 +520,75 @@ class HookQuerySetMixin:
|
|
|
520
520
|
# Fire hooks before DB ops
|
|
521
521
|
if not bypass_hooks:
|
|
522
522
|
ctx = HookContext(model_cls, bypass_hooks=False) # Pass bypass_hooks
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
523
|
+
|
|
524
|
+
if update_conflicts and unique_fields:
|
|
525
|
+
# For upsert operations, we need to determine which records will be created vs updated
|
|
526
|
+
# Check which records already exist in the database based on unique fields
|
|
527
|
+
existing_records = []
|
|
528
|
+
new_records = []
|
|
529
|
+
|
|
530
|
+
# Build a filter to check which records already exist
|
|
531
|
+
unique_values = []
|
|
532
|
+
for obj in objs:
|
|
533
|
+
unique_value = {}
|
|
534
|
+
for field_name in unique_fields:
|
|
535
|
+
if hasattr(obj, field_name):
|
|
536
|
+
unique_value[field_name] = getattr(obj, field_name)
|
|
537
|
+
if unique_value:
|
|
538
|
+
unique_values.append(unique_value)
|
|
539
|
+
|
|
540
|
+
if unique_values:
|
|
541
|
+
# Query the database to see which records already exist
|
|
542
|
+
from django.db.models import Q
|
|
543
|
+
existing_filters = Q()
|
|
544
|
+
for unique_value in unique_values:
|
|
545
|
+
filter_kwargs = {}
|
|
546
|
+
for field_name, value in unique_value.items():
|
|
547
|
+
filter_kwargs[field_name] = value
|
|
548
|
+
existing_filters |= Q(**filter_kwargs)
|
|
549
|
+
|
|
550
|
+
existing_pks = set(
|
|
551
|
+
model_cls.objects.filter(existing_filters).values_list('pk', flat=True)
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
# Separate records based on whether they already exist
|
|
555
|
+
for obj in objs:
|
|
556
|
+
obj_unique_value = {}
|
|
557
|
+
for field_name in unique_fields:
|
|
558
|
+
if hasattr(obj, field_name):
|
|
559
|
+
obj_unique_value[field_name] = getattr(obj, field_name)
|
|
560
|
+
|
|
561
|
+
# Check if this record already exists
|
|
562
|
+
if obj_unique_value:
|
|
563
|
+
existing_q = Q()
|
|
564
|
+
for field_name, value in obj_unique_value.items():
|
|
565
|
+
existing_q &= Q(**{field_name: value})
|
|
566
|
+
|
|
567
|
+
if model_cls.objects.filter(existing_q).exists():
|
|
568
|
+
existing_records.append(obj)
|
|
569
|
+
else:
|
|
570
|
+
new_records.append(obj)
|
|
571
|
+
else:
|
|
572
|
+
# If we can't determine uniqueness, treat as new
|
|
573
|
+
new_records.append(obj)
|
|
574
|
+
else:
|
|
575
|
+
# If no unique fields, treat all as new
|
|
576
|
+
new_records = objs
|
|
577
|
+
|
|
578
|
+
# Run validation hooks on all records
|
|
579
|
+
if not bypass_validation:
|
|
580
|
+
engine.run(model_cls, VALIDATE_CREATE, objs, ctx=ctx)
|
|
581
|
+
|
|
582
|
+
# Run appropriate BEFORE hooks based on what will happen
|
|
583
|
+
if new_records:
|
|
584
|
+
engine.run(model_cls, BEFORE_CREATE, new_records, ctx=ctx)
|
|
585
|
+
if existing_records:
|
|
586
|
+
engine.run(model_cls, BEFORE_UPDATE, existing_records, ctx=ctx)
|
|
587
|
+
else:
|
|
588
|
+
# For regular create operations, run create hooks before DB ops
|
|
589
|
+
if not bypass_validation:
|
|
590
|
+
engine.run(model_cls, VALIDATE_CREATE, objs, ctx=ctx)
|
|
591
|
+
engine.run(model_cls, BEFORE_CREATE, objs, ctx=ctx)
|
|
526
592
|
else:
|
|
527
593
|
ctx = HookContext(model_cls, bypass_hooks=True) # Pass bypass_hooks
|
|
528
594
|
logger.debug("bulk_create bypassed hooks")
|
|
@@ -557,9 +623,70 @@ class HookQuerySetMixin:
|
|
|
557
623
|
unique_fields=unique_fields,
|
|
558
624
|
)
|
|
559
625
|
|
|
560
|
-
# Fire
|
|
626
|
+
# Fire AFTER hooks
|
|
561
627
|
if not bypass_hooks:
|
|
562
|
-
|
|
628
|
+
if update_conflicts and unique_fields:
|
|
629
|
+
# For upsert operations, we need to determine which records were actually created vs updated
|
|
630
|
+
# Use the same logic as before to separate records
|
|
631
|
+
existing_records = []
|
|
632
|
+
new_records = []
|
|
633
|
+
|
|
634
|
+
# Build a filter to check which records already exist
|
|
635
|
+
unique_values = []
|
|
636
|
+
for obj in objs:
|
|
637
|
+
unique_value = {}
|
|
638
|
+
for field_name in unique_fields:
|
|
639
|
+
if hasattr(obj, field_name):
|
|
640
|
+
unique_value[field_name] = getattr(obj, field_name)
|
|
641
|
+
if unique_value:
|
|
642
|
+
unique_values.append(unique_value)
|
|
643
|
+
|
|
644
|
+
if unique_values:
|
|
645
|
+
# Query the database to see which records already exist
|
|
646
|
+
from django.db.models import Q
|
|
647
|
+
existing_filters = Q()
|
|
648
|
+
for unique_value in unique_values:
|
|
649
|
+
filter_kwargs = {}
|
|
650
|
+
for field_name, value in unique_value.items():
|
|
651
|
+
filter_kwargs[field_name] = value
|
|
652
|
+
existing_filters |= Q(**filter_kwargs)
|
|
653
|
+
|
|
654
|
+
existing_pks = set(
|
|
655
|
+
model_cls.objects.filter(existing_filters).values_list('pk', flat=True)
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
# Separate records based on whether they already exist
|
|
659
|
+
for obj in objs:
|
|
660
|
+
obj_unique_value = {}
|
|
661
|
+
for field_name in unique_fields:
|
|
662
|
+
if hasattr(obj, field_name):
|
|
663
|
+
obj_unique_value[field_name] = getattr(obj, field_name)
|
|
664
|
+
|
|
665
|
+
# Check if this record already exists
|
|
666
|
+
if obj_unique_value:
|
|
667
|
+
existing_q = Q()
|
|
668
|
+
for field_name, value in obj_unique_value.items():
|
|
669
|
+
existing_q &= Q(**{field_name: value})
|
|
670
|
+
|
|
671
|
+
if model_cls.objects.filter(existing_q).exists():
|
|
672
|
+
existing_records.append(obj)
|
|
673
|
+
else:
|
|
674
|
+
new_records.append(obj)
|
|
675
|
+
else:
|
|
676
|
+
# If we can't determine uniqueness, treat as new
|
|
677
|
+
new_records.append(obj)
|
|
678
|
+
else:
|
|
679
|
+
# If no unique fields, treat all as new
|
|
680
|
+
new_records = objs
|
|
681
|
+
|
|
682
|
+
# Run appropriate AFTER hooks based on what actually happened
|
|
683
|
+
if new_records:
|
|
684
|
+
engine.run(model_cls, AFTER_CREATE, new_records, ctx=ctx)
|
|
685
|
+
if existing_records:
|
|
686
|
+
engine.run(model_cls, AFTER_UPDATE, existing_records, ctx=ctx)
|
|
687
|
+
else:
|
|
688
|
+
# For regular create operations, run create hooks after DB ops
|
|
689
|
+
engine.run(model_cls, AFTER_CREATE, objs, ctx=ctx)
|
|
563
690
|
|
|
564
691
|
return result
|
|
565
692
|
|
|
@@ -9,9 +9,9 @@ django_bulk_hooks/handler.py,sha256=Bx-W6yyiciKMyy-BRxUt3CmRPCrX9_LhQgU-5LaJTjg,
|
|
|
9
9
|
django_bulk_hooks/manager.py,sha256=nfWiwU5-yAoxdnQsUMohxtyCpkV0MBv6X3wmipr9eQY,3697
|
|
10
10
|
django_bulk_hooks/models.py,sha256=WtSfc4GBOG_oOt8n37cVvid0MtFIGze9JYKSixil2y0,4370
|
|
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=whv6QunaxRhos0nBlx600mKeleovjdv3XdeMSULh7n8,60739
|
|
13
13
|
django_bulk_hooks/registry.py,sha256=GRUTGVQEO2sdkC9OaZ9Q3U7mM-3Ix83uTyvrlTtpatw,1317
|
|
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.252.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.252.dist-info/METADATA,sha256=xg9nPjRhZJPXem1plWls94mzENbAAoNiWI43J931rpE,9061
|
|
16
|
+
django_bulk_hooks-0.1.252.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
17
|
+
django_bulk_hooks-0.1.252.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|