django-bulk-hooks 0.2.52__tar.gz → 0.2.54__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.
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/PKG-INFO +1 -1
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/bulk_executor.py +17 -28
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/mti_handler.py +10 -1
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/pyproject.toml +1 -1
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/LICENSE +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/README.md +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/changeset.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/dispatcher.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/factory.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/helpers.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/__init__.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/analyzer.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/coordinator.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/field_utils.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/mti_plans.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/record_classifier.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/queryset.py +0 -0
- {django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/registry.py +0 -0
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/bulk_executor.py
RENAMED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
#
|
|
275
|
-
|
|
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
|
|
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
|
-
#
|
|
303
|
-
|
|
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
|
-
|
|
308
|
-
|
|
296
|
+
parent_pks_to_check.append(child_pk)
|
|
297
|
+
|
|
309
298
|
existing_child_pks = set()
|
|
310
|
-
if
|
|
299
|
+
if parent_pks_to_check:
|
|
311
300
|
existing_child_pks = set(
|
|
312
|
-
base_qs.filter(pk__in=
|
|
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)
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/mti_handler.py
RENAMED
|
@@ -406,7 +406,12 @@ class MTIHandler:
|
|
|
406
406
|
"""
|
|
407
407
|
child_obj = child_model()
|
|
408
408
|
|
|
409
|
-
# Copy field values (excluding AutoField and
|
|
409
|
+
# Copy field values (excluding AutoField, parent links, and inherited fields)
|
|
410
|
+
# In MTI, child objects should only have values for fields defined directly on the child model
|
|
411
|
+
parent_fields = set()
|
|
412
|
+
for parent_model in child_model._meta.parents.keys():
|
|
413
|
+
parent_fields.update(f.name for f in parent_model._meta.local_fields)
|
|
414
|
+
|
|
410
415
|
for field in child_model._meta.local_fields:
|
|
411
416
|
if isinstance(field, AutoField):
|
|
412
417
|
continue
|
|
@@ -417,6 +422,10 @@ class MTIHandler:
|
|
|
417
422
|
if child_model._meta.get_ancestor_link(field.related_model) == field:
|
|
418
423
|
continue
|
|
419
424
|
|
|
425
|
+
# Skip inherited fields - these belong to parent models
|
|
426
|
+
if field.name in parent_fields:
|
|
427
|
+
continue
|
|
428
|
+
|
|
420
429
|
if hasattr(source_obj, field.name):
|
|
421
430
|
# Use centralized field value extraction for consistent FK handling
|
|
422
431
|
value = get_field_value_for_db(source_obj, field.name, source_obj.__class__)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/__init__.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/analyzer.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/coordinator.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/field_utils.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.52 → django_bulk_hooks-0.2.54}/django_bulk_hooks/operations/mti_plans.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|