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.

@@ -1,10 +1,6 @@
1
- from django.db import models, transaction, connections
2
- from django.db.models import AutoField, Q, Max
3
- from django.db import NotSupportedError
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 individual saves (needed for PKs)
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, call our own logic recursively
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.123
3
+ Version: 0.1.124
4
4
  Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  License: MIT
6
6
  Keywords: django,bulk,hooks
@@ -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=19uG70BxNAJwLqu3j3ZmT4DStX8sPRwbV9079m0yn84,16717
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.123.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
- django_bulk_hooks-0.1.123.dist-info/METADATA,sha256=1irToq1BSI9i4dP80sqHhRDq3BhwGVcEK0B-Xf69xXo,6951
16
- django_bulk_hooks-0.1.123.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
17
- django_bulk_hooks-0.1.123.dist-info/RECORD,,
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,,