Skip to content

Instantly share code, notes, and snippets.

@fredkingham
Last active November 24, 2022 09:26
Show Gist options
  • Save fredkingham/a2a1ec8a3cc213416cd3c15dbe100ab3 to your computer and use it in GitHub Desktop.
Save fredkingham/a2a1ec8a3cc213416cd3c15dbe100ab3 to your computer and use it in GitHub Desktop.
Merges patients that have leading zeros.
from django.db import transaction
from opal.core import subrecords
from intrahospital_api import loader
from elcid.models import Demographics
from opal.models import Patient
from plugins.labtests.models import LabTest
subrecordsToIgnore = set([
'InitialPatientLoad',
'Demographics',
'ContactInformation',
'NextOfKinDetails',
'GPDetails',
'PositiveBloodCultureHistory',
'ICUHandover',
'ExternalDemographics',
])
# These are patients who will be manually merged.
TO_IGNORE = [
9421, 65695,
22235, 66313
]
@transaction.atomic
def merge_patients(from_patient, to_patient):
"""
Copies all non singleton subrecords from one patient to the other.
If the subrecords
"""
# Copy lab tests as we have lab tests that are older than
# those in the table
LabTest.objects.filter(patient_id=from_patient.id).update(
patient_id=to_patient.id
)
for subrecord_model in subrecords.patient_subrecords():
if subrecord_model._is_singleton:
from_subrecord = subrecord_model.objects.filter(
patient=from_patient
).get()
to_subrecord = subrecord_model.objects.filter(
patient=to_patient
).get()
if from_subrecord.updated:
if not to_subrecord.updated or from_subrecord.updated > to_subrecord.updated:
to_subrecord.delete()
from_subrecord.id = None
from_subrecord.patient_id = to_patient.id
from_subrecord.save()
else:
from_subrecords = list(subrecord_model.objects.filter(
patient=from_patient
))
for subrecord in from_subrecords:
subrecord.id = None
subrecord.patient_id = to_patient.id
subrecord.save()
for from_episode in from_patient.episode_set.all():
if not to_patient.episode_set.filter(category_name=from_episode.category_name).exists():
from_episode.id = None
from_episode.patient_id = to_patient.id
from_episode.save()
else:
to_episode = to_patient.episode_set.filter(category_name=from_episode.category_name).get()
for subrecord_model in subrecords.episode_subrecords():
if subrecord_model._is_singleton:
from_subrecord = subrecord_model.objects.filter(
episode=from_episode
).get()
to_subrecord = subrecord_model.objects.filter(
episode=to_episode
).get()
if from_subrecord.updated:
if not to_subrecord.updated or from_subrecord.updated > to_subrecord.updated:
to_subrecord.delete()
from_subrecord.id = None
from_subrecord.episode_id = to_episode.id
from_subrecord.save()
else:
from_subrecords = list(subrecord_model.objects.filter(
episode=from_episode
))
for subrecord in from_subrecords:
subrecord.id = None
subrecord.episode_id = to_episode.id
subrecord.save()
loader.load_patient(to_patient)
from_patient.delete()
def has_elcid_native_records(patient):
result = []
for subrecord in subrecords.episode_subrecords():
if subrecord._is_singleton:
result.extend(subrecord.objects.filter(episode__patient_id=patient.id).exclude(updated=None))
else:
result.extend(subrecord.objects.filter(episode__patient_id=patient.id))
for subrecord in subrecords.patient_subrecords():
if subrecord.__name__ in subrecordsToIgnore:
continue
if subrecord._is_singleton:
result.extend(subrecord.objects.filter(patient_id=patient.id).exclude(updated=None))
else:
result.extend(subrecord.objects.filter(patient_id=patient.id))
return result
@transaction.atomic
def merge_non_zeros():
demos = Demographics.objects.filter(hospital_number__startswith='0').exclude(
patient_id__in=TO_IGNORE
).select_related('patient')
print(f'Looking at {demos.count()} patients')
for demo in demos:
with_zero_hn = demo.hospital_number
without_zero_hn = with_zero_hn.lstrip('0')
if not len(without_zero_hn):
print(f'no hn for patient {with_zero_hn}, skipping')
continue
without_zero_patients = list(Patient.objects.filter(demographics__hospital_number=without_zero_hn))
if len(without_zero_patients) > 1:
raise ValueError(f'Duplicate patients found for hn {without_zero_hn}')
if len(without_zero_patients):
without_zero_patient = without_zero_patients[0]
if not has_elcid_native_records(demo.patient):
# No elcid native entries on the 0 prefix, delete
print(f'no elcid records for patient {demo.hospital_number} and we have non zero, deleting')
demo.patient.delete()
continue
else:
merge_patients(demo.patient, without_zero_patient)
print(f'merging {demo.hospital_number} to {without_zero_hn}')
else:
print(f'No with zero patient, changing hn from {with_zero_hn} to {without_zero_hn}')
demo.hospital_number = without_zero_hn
demo.save()
loader.load_patient(demo.patient)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment