django-bulk-hooks 0.2.49__tar.gz → 0.2.50__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 (26) hide show
  1. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/bulk_executor.py +34 -10
  3. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/pyproject.toml +1 -1
  4. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/LICENSE +0 -0
  5. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/README.md +0 -0
  6. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/__init__.py +0 -0
  7. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/changeset.py +0 -0
  8. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/conditions.py +0 -0
  9. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/constants.py +0 -0
  10. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/context.py +0 -0
  11. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/decorators.py +0 -0
  12. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/dispatcher.py +0 -0
  13. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/enums.py +0 -0
  14. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/factory.py +0 -0
  15. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/handler.py +0 -0
  16. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/helpers.py +0 -0
  17. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/manager.py +0 -0
  18. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/models.py +0 -0
  19. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/__init__.py +0 -0
  20. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/analyzer.py +0 -0
  21. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/coordinator.py +0 -0
  22. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/mti_handler.py +0 -0
  23. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/mti_plans.py +0 -0
  24. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/operations/record_classifier.py +0 -0
  25. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/django_bulk_hooks/queryset.py +0 -0
  26. {django_bulk_hooks-0.2.49 → django_bulk_hooks-0.2.50}/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.49
3
+ Version: 0.2.50
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
@@ -243,9 +243,11 @@ class BulkExecutor:
243
243
  # Copy generated fields back to parent objects
244
244
  for upserted_parent, parent_obj in zip(upserted_parents, parent_level.objects):
245
245
  for field in parent_level.model_class._meta.local_fields:
246
- upserted_value = getattr(upserted_parent, field.name, None)
246
+ # Use attname for ForeignKey fields to avoid triggering database queries
247
+ field_attr = field.attname if isinstance(field, ForeignKey) else field.name
248
+ upserted_value = getattr(upserted_parent, field_attr, None)
247
249
  if upserted_value is not None:
248
- setattr(parent_obj, field.name, upserted_value)
250
+ setattr(parent_obj, field_attr, upserted_value)
249
251
 
250
252
  parent_obj._state.adding = False
251
253
  parent_obj._state.db = self.queryset.db
@@ -291,14 +293,36 @@ class BulkExecutor:
291
293
  # In MTI, child objects get PKs from parent links, but we need to distinguish
292
294
  # between truly new records and existing records for upsert operations
293
295
  objs_without_pk, objs_with_pk = [], []
294
- for child_obj, orig_obj in zip(plan.child_objects, plan.original_objects):
295
- # Check if this is an existing record (for upsert operations)
296
- if id(orig_obj) in plan.existing_record_ids:
297
- # Existing record - should be updated
298
- objs_with_pk.append(child_obj)
299
- else:
300
- # New record - should be inserted
301
- objs_without_pk.append(child_obj)
296
+
297
+ # Check which CHILD records actually exist in the child table
298
+ # This is separate from checking parent existence
299
+ if plan.update_conflicts:
300
+ # Query the CHILD table to see which child records exist
301
+ parent_pks = []
302
+ for child_obj in plan.child_objects:
303
+ child_pk = getattr(child_obj, plan.child_model._meta.pk.attname, None)
304
+ if child_pk:
305
+ parent_pks.append(child_pk)
306
+
307
+ existing_child_pks = set()
308
+ if parent_pks:
309
+ existing_child_pks = set(
310
+ base_qs.filter(pk__in=parent_pks).values_list('pk', flat=True)
311
+ )
312
+
313
+ # Split based on whether child record exists
314
+ for child_obj in plan.child_objects:
315
+ child_pk = getattr(child_obj, plan.child_model._meta.pk.attname, None)
316
+ if child_pk and child_pk in existing_child_pks:
317
+ # Child record exists - update it
318
+ objs_with_pk.append(child_obj)
319
+ else:
320
+ # Child record doesn't exist - insert it
321
+ objs_without_pk.append(child_obj)
322
+ else:
323
+ # Not an upsert - all are new records
324
+ objs_without_pk = plan.child_objects
325
+ objs_with_pk = []
302
326
 
303
327
  # For objects with PK (existing records in upsert), use bulk_update
304
328
  if objs_with_pk and plan.update_fields:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.2.49"
3
+ version = "0.2.50"
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"