django-bulk-hooks 0.2.57__py3-none-any.whl → 0.2.58__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/operations/mti_handler.py +39 -0
- {django_bulk_hooks-0.2.57.dist-info → django_bulk_hooks-0.2.58.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.2.57.dist-info → django_bulk_hooks-0.2.58.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.2.57.dist-info → django_bulk_hooks-0.2.58.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.2.57.dist-info → django_bulk_hooks-0.2.58.dist-info}/WHEEL +0 -0
|
@@ -306,6 +306,14 @@ class MTIHandler:
|
|
|
306
306
|
if not filtered_updates and normalized_unique:
|
|
307
307
|
filtered_updates = [normalized_unique[0]]
|
|
308
308
|
|
|
309
|
+
# CRITICAL FIX: Always include auto_now fields in updates to ensure timestamps are updated.
|
|
310
|
+
# During MTI upsert, parent tables need auto_now fields updated even when only child fields change.
|
|
311
|
+
# This ensures parent-level timestamps (e.g., updated_at) refresh correctly on upsert.
|
|
312
|
+
auto_now_fields = self._get_auto_now_fields_for_model(model_class, model_fields_by_name)
|
|
313
|
+
if auto_now_fields:
|
|
314
|
+
# Convert to set to avoid duplicates, then back to list for consistency
|
|
315
|
+
filtered_updates = list(set(filtered_updates) | set(auto_now_fields))
|
|
316
|
+
|
|
309
317
|
# Only enable upsert if we have fields to update (real or dummy)
|
|
310
318
|
if filtered_updates:
|
|
311
319
|
level_update_conflicts = True
|
|
@@ -334,6 +342,14 @@ class MTIHandler:
|
|
|
334
342
|
]
|
|
335
343
|
level_update_fields = available_fields[:1] if available_fields else [pk_field.name]
|
|
336
344
|
|
|
345
|
+
# CRITICAL FIX: Include auto_now fields in update_fields to ensure timestamps are updated.
|
|
346
|
+
# During MTI upsert, parent tables need auto_now fields updated even when using dummy fields.
|
|
347
|
+
# This ensures parent-level timestamps (e.g., updated_at) refresh correctly on upsert.
|
|
348
|
+
auto_now_fields = self._get_auto_now_fields_for_model(model_class, model_fields_by_name)
|
|
349
|
+
if auto_now_fields:
|
|
350
|
+
# Convert to set to avoid duplicates, then back to list for consistency
|
|
351
|
+
level_update_fields = list(set(level_update_fields) | set(auto_now_fields))
|
|
352
|
+
|
|
337
353
|
# Create parent level
|
|
338
354
|
parent_level = ParentLevel(
|
|
339
355
|
model_class=model_class,
|
|
@@ -347,6 +363,29 @@ class MTIHandler:
|
|
|
347
363
|
|
|
348
364
|
return parent_levels
|
|
349
365
|
|
|
366
|
+
def _get_auto_now_fields_for_model(self, model_class, model_fields_by_name):
|
|
367
|
+
"""
|
|
368
|
+
Get auto_now (not auto_now_add) fields for a specific model.
|
|
369
|
+
|
|
370
|
+
Only includes fields that exist in model_fields_by_name to ensure
|
|
371
|
+
they're valid local fields for this model level.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
model_class: Model class to get fields for
|
|
375
|
+
model_fields_by_name: Dict of valid field names for this model level
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
List of auto_now field names (excluding auto_now_add)
|
|
379
|
+
"""
|
|
380
|
+
auto_now_fields = []
|
|
381
|
+
for field in model_class._meta.local_fields:
|
|
382
|
+
# Only include auto_now (not auto_now_add) since auto_now_add should only be set on creation
|
|
383
|
+
if getattr(field, "auto_now", False) and not getattr(field, "auto_now_add", False):
|
|
384
|
+
# Double-check field exists in model_fields_by_name for safety
|
|
385
|
+
if field.name in model_fields_by_name:
|
|
386
|
+
auto_now_fields.append(field.name)
|
|
387
|
+
return auto_now_fields
|
|
388
|
+
|
|
350
389
|
def _has_matching_constraint(self, model_class, normalized_unique):
|
|
351
390
|
"""Check if model has a unique constraint matching the given fields."""
|
|
352
391
|
try:
|
|
@@ -16,12 +16,12 @@ django_bulk_hooks/operations/analyzer.py,sha256=wAG8sAG9NwfwNqG9z81VfGR7AANDzRmM
|
|
|
16
16
|
django_bulk_hooks/operations/bulk_executor.py,sha256=Y-wkvuV_X-SZmI965JVrrtwbzPZVggUfy8mR1pzP9d0,27048
|
|
17
17
|
django_bulk_hooks/operations/coordinator.py,sha256=iGavJLqe3eYRqFay8cMn6muwyRYzQo-HFGphsS5hL6g,30799
|
|
18
18
|
django_bulk_hooks/operations/field_utils.py,sha256=Tvr5bcZLG8imH-r2S85oui1Cbw6hGv3VtuIMn4OvsU4,2895
|
|
19
|
-
django_bulk_hooks/operations/mti_handler.py,sha256=
|
|
19
|
+
django_bulk_hooks/operations/mti_handler.py,sha256=173jghcxCE5UEZxM1QJRS-lWg0-KJxCQCbWHVKppIEM,26000
|
|
20
20
|
django_bulk_hooks/operations/mti_plans.py,sha256=7STQ2oA2ZT8cEG3-t-6xciRAdf7OeSf0gRLXR_BRG-Q,3363
|
|
21
21
|
django_bulk_hooks/operations/record_classifier.py,sha256=kqML4aO11X9K3SSJ5DUlUukwI172j_Tk12Kr77ee8q8,7065
|
|
22
22
|
django_bulk_hooks/queryset.py,sha256=aQitlbexcVnmeAdc0jtO3hci39p4QEu4srQPEzozy5s,5546
|
|
23
23
|
django_bulk_hooks/registry.py,sha256=uum5jhGI3TPaoiXuA1MdBdu4gbE3rQGGwQ5YDjiMcjk,7949
|
|
24
|
-
django_bulk_hooks-0.2.
|
|
25
|
-
django_bulk_hooks-0.2.
|
|
26
|
-
django_bulk_hooks-0.2.
|
|
27
|
-
django_bulk_hooks-0.2.
|
|
24
|
+
django_bulk_hooks-0.2.58.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
25
|
+
django_bulk_hooks-0.2.58.dist-info/METADATA,sha256=kVna-_dN9xVNaMMZHZUzm-Ab4IjhVzA1L8XXPms5T7o,9265
|
|
26
|
+
django_bulk_hooks-0.2.58.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
27
|
+
django_bulk_hooks-0.2.58.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|