django-bulk-hooks 0.1.123__py3-none-any.whl → 0.1.124__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 +35 -24
- {django_bulk_hooks-0.1.123.dist-info → django_bulk_hooks-0.1.124.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.1.123.dist-info → django_bulk_hooks-0.1.124.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.1.123.dist-info → django_bulk_hooks-0.1.124.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.1.123.dist-info → django_bulk_hooks-0.1.124.dist-info}/WHEEL +0 -0
django_bulk_hooks/queryset.py
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
from django.db
|
|
3
|
-
from django.db import
|
|
4
|
-
from django.db.models.constants import OnConflict
|
|
5
|
-
from django.db.models.expressions import DatabaseDefault
|
|
6
|
-
import operator
|
|
7
|
-
from functools import reduce
|
|
1
|
+
|
|
2
|
+
from django.db import models, transaction
|
|
3
|
+
from django.db.models import AutoField
|
|
8
4
|
|
|
9
5
|
from django_bulk_hooks import engine
|
|
10
6
|
from django_bulk_hooks.constants import (
|
|
@@ -303,8 +299,11 @@ class HookQuerySet(models.QuerySet):
|
|
|
303
299
|
"""
|
|
304
300
|
Process a single batch of objects through the inheritance chain.
|
|
305
301
|
"""
|
|
306
|
-
# Step 1: Handle parent tables with
|
|
302
|
+
# Step 1: Handle parent tables with bulk operations where possible
|
|
307
303
|
parent_objects_map = {}
|
|
304
|
+
|
|
305
|
+
# Group parent objects by model class to enable bulk operations
|
|
306
|
+
parent_objects_by_model = {}
|
|
308
307
|
for obj in batch:
|
|
309
308
|
parent_instances = {}
|
|
310
309
|
current_parent = None
|
|
@@ -312,10 +311,24 @@ class HookQuerySet(models.QuerySet):
|
|
|
312
311
|
parent_obj = self._create_parent_instance(
|
|
313
312
|
obj, model_class, current_parent
|
|
314
313
|
)
|
|
315
|
-
parent_obj.save()
|
|
316
314
|
parent_instances[model_class] = parent_obj
|
|
317
315
|
current_parent = parent_obj
|
|
316
|
+
|
|
317
|
+
# Group by model class for potential bulk operations
|
|
318
|
+
if model_class not in parent_objects_by_model:
|
|
319
|
+
parent_objects_by_model[model_class] = []
|
|
320
|
+
parent_objects_by_model[model_class].append(parent_obj)
|
|
321
|
+
|
|
318
322
|
parent_objects_map[id(obj)] = parent_instances
|
|
323
|
+
|
|
324
|
+
# Save parent objects in bulk where possible
|
|
325
|
+
for model_class, parent_objs in parent_objects_by_model.items():
|
|
326
|
+
if len(parent_objs) > 1:
|
|
327
|
+
# Use bulk_create for multiple objects of the same model
|
|
328
|
+
model_class._base_manager.bulk_create(parent_objs)
|
|
329
|
+
else:
|
|
330
|
+
# Individual save for single objects
|
|
331
|
+
super(parent_objs[0].__class__, parent_objs[0]).save()
|
|
319
332
|
# Step 2: Bulk insert for child objects
|
|
320
333
|
child_model = inheritance_chain[-1]
|
|
321
334
|
child_objects = []
|
|
@@ -324,22 +337,8 @@ class HookQuerySet(models.QuerySet):
|
|
|
324
337
|
obj, child_model, parent_objects_map.get(id(obj), {})
|
|
325
338
|
)
|
|
326
339
|
child_objects.append(child_obj)
|
|
327
|
-
# If the child model is still MTI,
|
|
340
|
+
# If the child model is still MTI, we need to handle it specially
|
|
328
341
|
if len([p for p in child_model._meta.parents.keys() if not p._meta.proxy]) > 0:
|
|
329
|
-
# Build inheritance chain for the child model
|
|
330
|
-
child_inheritance_chain = []
|
|
331
|
-
current_model = child_model
|
|
332
|
-
while current_model:
|
|
333
|
-
if not current_model._meta.proxy:
|
|
334
|
-
child_inheritance_chain.append(current_model)
|
|
335
|
-
parents = [
|
|
336
|
-
parent
|
|
337
|
-
for parent in current_model._meta.parents.keys()
|
|
338
|
-
if not parent._meta.proxy
|
|
339
|
-
]
|
|
340
|
-
current_model = parents[0] if parents else None
|
|
341
|
-
child_inheritance_chain.reverse()
|
|
342
|
-
|
|
343
342
|
# For nested MTI, we can't use bulk operations recursively
|
|
344
343
|
# because it would create infinite recursion. Instead, we save each child individually.
|
|
345
344
|
# We use super().save() to avoid triggering hooks that would cause recursion.
|
|
@@ -388,6 +387,12 @@ class HookQuerySet(models.QuerySet):
|
|
|
388
387
|
elif hasattr(field, 'auto_now') and field.auto_now:
|
|
389
388
|
field.pre_save(parent_obj, add=True)
|
|
390
389
|
|
|
390
|
+
# Ensure auto_now_add fields are explicitly set to prevent null constraint violations
|
|
391
|
+
for field in parent_model._meta.local_fields:
|
|
392
|
+
if hasattr(field, 'auto_now_add') and field.auto_now_add:
|
|
393
|
+
if getattr(parent_obj, field.name) is None:
|
|
394
|
+
field.pre_save(parent_obj, add=True)
|
|
395
|
+
|
|
391
396
|
return parent_obj
|
|
392
397
|
|
|
393
398
|
def _create_child_instance(self, source_obj, child_model, parent_instances):
|
|
@@ -411,4 +416,10 @@ class HookQuerySet(models.QuerySet):
|
|
|
411
416
|
elif hasattr(field, 'auto_now') and field.auto_now:
|
|
412
417
|
field.pre_save(child_obj, add=True)
|
|
413
418
|
|
|
419
|
+
# Ensure auto_now_add fields are explicitly set to prevent null constraint violations
|
|
420
|
+
for field in child_model._meta.local_fields:
|
|
421
|
+
if hasattr(field, 'auto_now_add') and field.auto_now_add:
|
|
422
|
+
if getattr(child_obj, field.name) is None:
|
|
423
|
+
field.pre_save(child_obj, add=True)
|
|
424
|
+
|
|
414
425
|
return child_obj
|
|
@@ -9,9 +9,9 @@ django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,
|
|
|
9
9
|
django_bulk_hooks/manager.py,sha256=r54ct3S6AcqME2OsX-jPF944CEKcoSIW3qiAx_NwUaw,2801
|
|
10
10
|
django_bulk_hooks/models.py,sha256=7RG7GrOdHXFjGVPV4FPRZVNMIHHW-hMCi6hn9LH_hVI,3331
|
|
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=RpPaATYlJR6mCoxwCKUcVPH0Wr0Rwl51yF9FDjTT4TQ,17433
|
|
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.124.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.124.dist-info/METADATA,sha256=Ul83KdLsZ_wvBSeVQJkG2Mf_HHg5Ckjrck5dVIwZ0FU,6951
|
|
16
|
+
django_bulk_hooks-0.1.124.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
17
|
+
django_bulk_hooks-0.1.124.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|