django-bulk-hooks 0.2.52__tar.gz → 0.2.53__tar.gz

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.

Files changed (27) hide show
  1. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/bulk_executor.py +17 -28
  3. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/mti_handler.py +2 -6
  4. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/pyproject.toml +1 -1
  5. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/LICENSE +0 -0
  6. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/README.md +0 -0
  7. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/__init__.py +0 -0
  8. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/changeset.py +0 -0
  9. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/conditions.py +0 -0
  10. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/constants.py +0 -0
  11. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/context.py +0 -0
  12. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/decorators.py +0 -0
  13. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/dispatcher.py +0 -0
  14. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/enums.py +0 -0
  15. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/factory.py +0 -0
  16. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/handler.py +0 -0
  17. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/helpers.py +0 -0
  18. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/manager.py +0 -0
  19. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/models.py +0 -0
  20. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/__init__.py +0 -0
  21. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/analyzer.py +0 -0
  22. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/coordinator.py +0 -0
  23. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/field_utils.py +0 -0
  24. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/mti_plans.py +0 -0
  25. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/operations/record_classifier.py +0 -0
  26. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/queryset.py +0 -0
  27. {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.53}/django_bulk_hooks/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.2.52
3
+ Version: 0.2.53
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
@@ -261,57 +261,46 @@ class BulkExecutor:
261
261
  parent_instances_map[orig_obj_id] = {}
262
262
  parent_instances_map[orig_obj_id][parent_level.model_class] = parent_obj
263
263
 
264
- # Step 2: Add parent links to child objects and set PKs for existing records
264
+ # Step 2: Add parent links to child objects and set PKs appropriately
265
265
  for child_obj, orig_obj in zip(plan.child_objects, plan.original_objects):
266
266
  parent_instances = parent_instances_map.get(id(orig_obj), {})
267
267
 
268
- # Set parent links
268
+ # Set parent links and PKs for all objects (since in MTI, child PK = parent PK)
269
269
  for parent_model, parent_instance in parent_instances.items():
270
270
  parent_link = plan.child_model._meta.get_ancestor_link(parent_model)
271
271
  if parent_link:
272
- setattr(child_obj, parent_link.attname, parent_instance.pk)
272
+ parent_pk = parent_instance.pk
273
+ setattr(child_obj, parent_link.attname, parent_pk)
273
274
  setattr(child_obj, parent_link.name, parent_instance)
274
- # IMPORTANT: Don't set the child's PK here - it should only get PK after insertion
275
- # The parent link field (hookmodel_ptr) is NOT the same as the child's PK
275
+ # In MTI, the child PK IS the parent link
276
+ child_obj.pk = parent_pk
277
+ child_obj.id = parent_pk
276
278
  else:
277
279
  logger.warning(f"No parent link found for {parent_model} in {plan.child_model}")
278
280
 
279
- # For existing records in upsert, ensure PK is set on child object
280
- if id(orig_obj) in plan.existing_record_ids:
281
- pk_value = getattr(orig_obj, "pk", None)
282
- if pk_value:
283
- child_obj.pk = pk_value
284
- child_obj.id = pk_value
285
- else:
286
- # If no PK on original object, this is a new record, don't set PK
287
- logger.info(f"New record {orig_obj} - not setting PK on child object")
288
-
289
281
  # Step 3: Handle child objects
290
282
  # Note: We can't use bulk_create on child MTI models, so we use _batched_insert for new records
291
283
  # and bulk_update for existing records
292
284
  base_qs = BaseQuerySet(model=plan.child_model, using=self.queryset.db)
293
-
294
- # For MTI child objects, we need to handle them differently
295
- # In MTI, child objects get PKs from parent links, but we need to distinguish
296
- # between truly new records and existing records for upsert operations
285
+
286
+ # For MTI child objects, we need to distinguish between truly new records and existing records for upsert operations
297
287
  objs_without_pk, objs_with_pk = [], []
298
-
288
+
299
289
  # Check which CHILD records actually exist in the child table
300
- # This is separate from checking parent existence
301
290
  if plan.update_conflicts:
302
- # Query the CHILD table to see which child records exist
303
- parent_pks = []
291
+ # For upsert, check which child records exist based on the parent PKs
292
+ parent_pks_to_check = []
304
293
  for child_obj in plan.child_objects:
305
294
  child_pk = getattr(child_obj, plan.child_model._meta.pk.attname, None)
306
295
  if child_pk:
307
- parent_pks.append(child_pk)
308
-
296
+ parent_pks_to_check.append(child_pk)
297
+
309
298
  existing_child_pks = set()
310
- if parent_pks:
299
+ if parent_pks_to_check:
311
300
  existing_child_pks = set(
312
- base_qs.filter(pk__in=parent_pks).values_list('pk', flat=True)
301
+ base_qs.filter(pk__in=parent_pks_to_check).values_list('pk', flat=True)
313
302
  )
314
-
303
+
315
304
  # Split based on whether child record exists
316
305
  for child_obj in plan.child_objects:
317
306
  child_pk = getattr(child_obj, plan.child_model._meta.pk.attname, None)
@@ -193,12 +193,8 @@ class MTIHandler:
193
193
  if existing_pks_map is None:
194
194
  existing_pks_map = {}
195
195
 
196
- # Set PKs on existing objects so they can be updated
197
- if existing_pks_map:
198
- for obj in objs:
199
- if id(obj) in existing_pks_map:
200
- obj.pk = existing_pks_map[id(obj)]
201
- obj.id = existing_pks_map[id(obj)]
196
+ # For upsert operations, don't set PKs on source objects - let Django's bulk_create handle it
197
+ # The PKs will be set on the resulting objects after the bulk operation
202
198
 
203
199
  # Build parent levels
204
200
  parent_levels = self._build_parent_levels(
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.2.52"
3
+ version = "0.2.53"
4
4
  description = "Hook-style hooks for Django bulk operations like bulk_create and bulk_update."
5
5
  authors = ["Konrad Beck <konrad.beck@merchantcapital.co.za>"]
6
6
  readme = "README.md"