Delete a segment using optimized bulk operations. Uses bulk UPDATE/DELETE operations instead of individual soft-deletes, reducing the number of database queries from O(n) to O(1) where n is the number of rules and conditions. Note: This is a temporary solution until we redesig
(
segment: "Segment",
author: AuthorData,
)
| 11 | |
| 12 | |
| 13 | def delete_segment( |
| 14 | segment: "Segment", |
| 15 | author: AuthorData, |
| 16 | ) -> None: |
| 17 | """ |
| 18 | Delete a segment using optimized bulk operations. |
| 19 | |
| 20 | Uses bulk UPDATE/DELETE operations instead of individual soft-deletes, |
| 21 | reducing the number of database queries from O(n) to O(1) where n is |
| 22 | the number of rules and conditions. |
| 23 | |
| 24 | Note: This is a temporary solution until we redesign the segment data model. |
| 25 | """ |
| 26 | from features.models import FeatureSegment |
| 27 | from segments.models import Condition, Segment, SegmentRule |
| 28 | from segments.tasks import create_segment_deleted_audit_log |
| 29 | |
| 30 | now = timezone.now() |
| 31 | |
| 32 | segment_name = segment.name |
| 33 | segment_uuid = str(segment.uuid) |
| 34 | segment_id = segment.id |
| 35 | project_id = segment.project_id |
| 36 | |
| 37 | segment_ids = list( |
| 38 | Segment.objects.filter( |
| 39 | models.Q(id=segment.id) | models.Q(version_of_id=segment.id) |
| 40 | ).values_list("id", flat=True) |
| 41 | ) |
| 42 | |
| 43 | top_level_rule_ids = list( |
| 44 | SegmentRule.objects.filter(segment_id__in=segment_ids).values_list( |
| 45 | "id", flat=True |
| 46 | ) |
| 47 | ) |
| 48 | |
| 49 | all_rule_ids = set(top_level_rule_ids) |
| 50 | current_level_ids = top_level_rule_ids |
| 51 | |
| 52 | while current_level_ids: |
| 53 | nested_rule_ids = list( |
| 54 | SegmentRule.objects.filter(rule_id__in=current_level_ids).values_list( |
| 55 | "id", flat=True |
| 56 | ) |
| 57 | ) |
| 58 | all_rule_ids.update(nested_rule_ids) |
| 59 | current_level_ids = nested_rule_ids |
| 60 | |
| 61 | all_rule_ids_list = list(all_rule_ids) |
| 62 | |
| 63 | with transaction.atomic(): |
| 64 | FeatureSegment.objects.filter(segment_id__in=segment_ids).delete() |
| 65 | Condition.objects.filter(rule_id__in=all_rule_ids_list).update(deleted_at=now) |
| 66 | SegmentRule.objects.filter(id__in=all_rule_ids_list).update(deleted_at=now) |
| 67 | Segment.objects.filter(id__in=segment_ids).update(deleted_at=now) |
| 68 | |
| 69 | create_segment_deleted_audit_log.delay( |
| 70 | args=( |
searching dependent graphs…