diff --git a/classification/models/condition_text_matching.py b/classification/models/condition_text_matching.py index d8b5fc62b..f6ae2e8fb 100644 --- a/classification/models/condition_text_matching.py +++ b/classification/models/condition_text_matching.py @@ -338,64 +338,67 @@ def sync_condition_text_classification(cm: ClassificationModification, update_co ct: ConditionText ct, ct_is_new = ConditionText.objects.get_or_create(normalized_text=normalized, lab=lab) - # ensure each step of the hierarchy is present - root, new_root = ConditionTextMatch.objects.get_or_create( - condition_text=ct, - gene_symbol=None, - mode_of_inheritance=None, - classification=None - ) - - gene_level, new_gene_level = ConditionTextMatch.objects.get_or_create( - parent=root, - condition_text=ct, - gene_symbol=gene_symbol, - mode_of_inheritance=None, - classification=None - ) - - mode_of_inheritance_level, _ = ConditionTextMatch.objects.get_or_create( - parent=gene_level, - condition_text=ct, - gene_symbol=gene_symbol, - mode_of_inheritance=mode_of_inheritance, - classification=None - ) - - if existing: - if existing.parent != mode_of_inheritance_level or \ - existing.condition_text != ct or \ - existing.gene_symbol != gene_symbol or \ - existing.mode_of_inheritance != mode_of_inheritance: - - # update existing to new hierarchy - # assume if a condition has been set for this classification specifically that it's - # still valid - old_text = existing.condition_text - existing.parent = mode_of_inheritance_level - existing.condition_text = ct - existing.mode_of_inheritance = mode_of_inheritance - existing.save() - if update_counts: - update_condition_text_match_counts(old_text) - old_text.save() - else: - # nothing has changed, no need to update anything - return - else: - ConditionTextMatch.objects.create( - parent=mode_of_inheritance_level, + ct = ConditionText.objects.select_for_update().filter(pk=ct.pk).first() + with transaction.atomic(): + + # ensure each step of the hierarchy is present + root, new_root = ConditionTextMatch.objects.get_or_create( + condition_text=ct, + gene_symbol=None, + mode_of_inheritance=None, + classification=None + ) + + gene_level, new_gene_level = ConditionTextMatch.objects.get_or_create( + parent=root, + condition_text=ct, + gene_symbol=gene_symbol, + mode_of_inheritance=None, + classification=None + ) + + mode_of_inheritance_level, _ = ConditionTextMatch.objects.get_or_create( + parent=gene_level, condition_text=ct, gene_symbol=gene_symbol, mode_of_inheritance=mode_of_inheritance, - classification=classification + classification=None ) - if attempt_automatch and (new_root or new_gene_level): - ConditionTextMatch.attempt_automatch(ct, gene_symbol=gene_symbol) - elif update_counts: # attempt automatch update counts - update_condition_text_match_counts(ct) - ct.save() + if existing: + if existing.parent != mode_of_inheritance_level or \ + existing.condition_text != ct or \ + existing.gene_symbol != gene_symbol or \ + existing.mode_of_inheritance != mode_of_inheritance: + + # update existing to new hierarchy + # assume if a condition has been set for this classification specifically that it's + # still valid + old_text = existing.condition_text + existing.parent = mode_of_inheritance_level + existing.condition_text = ct + existing.mode_of_inheritance = mode_of_inheritance + existing.save() + if update_counts: + update_condition_text_match_counts(old_text) + old_text.save() + else: + # nothing has changed, no need to update anything + return + else: + ConditionTextMatch.objects.create( + parent=mode_of_inheritance_level, + condition_text=ct, + gene_symbol=gene_symbol, + mode_of_inheritance=mode_of_inheritance, + classification=classification + ) + + if attempt_automatch and (new_root or new_gene_level): + ConditionTextMatch.attempt_automatch(ct, gene_symbol=gene_symbol) + elif update_counts: # attempt automatch update counts + update_condition_text_match_counts(ct) + ct.save() def as_resolved_condition(self) -> Optional[ConditionResolvedDict]: """