From 8842358d7ff9d6c2de86ca15abb7ea8c68e9aefc Mon Sep 17 00:00:00 2001 From: Olivier Leger Date: Tue, 24 Oct 2023 10:56:48 -0400 Subject: [PATCH] Skip redundant queries to DB --- .../commands/soft_delete_orphan_attachments.py | 7 +++++-- onadata/apps/logger/models/xform.py | 14 ++++++++++---- onadata/apps/logger/xform_instance_parser.py | 3 +-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/onadata/apps/logger/management/commands/soft_delete_orphan_attachments.py b/onadata/apps/logger/management/commands/soft_delete_orphan_attachments.py index c2520e396..dfd5a73c0 100644 --- a/onadata/apps/logger/management/commands/soft_delete_orphan_attachments.py +++ b/onadata/apps/logger/management/commands/soft_delete_orphan_attachments.py @@ -11,7 +11,6 @@ ) from onadata.apps.logger.signals import pre_delete_attachment from onadata.libs.utils.logger_tools import get_soft_deleted_attachments -from onadata.apps.viewer.models.parsed_instance import datetime_from_str class Command(BaseCommand): @@ -62,7 +61,9 @@ def handle(self, *args, **kwargs): 'to run on big databases' ) - instance_ids = Attachment.objects.values_list('instance_id', flat=True).distinct() + instance_ids = Attachment.objects.values_list( + 'instance_id', flat=True + ).distinct() if start_id: instance_ids = instance_ids.filter(instance_id__gte=start_id) @@ -112,6 +113,8 @@ def handle(self, *args, **kwargs): continue for soft_deleted_attachment in soft_deleted_attachments: + # Avoid fetching Instance object once again + soft_deleted_attachment.instance = instance pre_delete_attachment( soft_deleted_attachment, only_update_counters=True ) diff --git a/onadata/apps/logger/models/xform.py b/onadata/apps/logger/models/xform.py index 146a31e9a..84995d3ec 100644 --- a/onadata/apps/logger/models/xform.py +++ b/onadata/apps/logger/models/xform.py @@ -2,6 +2,7 @@ import json import os import re +from copy import deepcopy from io import BytesIO from xml.sax.saxutils import escape as xml_escape @@ -129,10 +130,15 @@ def url(self): } ) - def data_dictionary(self): - from onadata.apps.viewer.models.data_dictionary import\ - DataDictionary - return DataDictionary.all_objects.get(pk=self.pk) + def data_dictionary(self, use_cache: bool = False): + from onadata.apps.viewer.models.data_dictionary import DataDictionary + + if not use_cache: + return DataDictionary.all_objects.get(pk=self.pk) + + xform_dict = deepcopy(self.__dict__) + xform_dict.pop('_state', None) + return DataDictionary(**xform_dict) @property def has_instances_with_geopoints(self): diff --git a/onadata/apps/logger/xform_instance_parser.py b/onadata/apps/logger/xform_instance_parser.py index cea69d0ba..a6c21c8de 100644 --- a/onadata/apps/logger/xform_instance_parser.py +++ b/onadata/apps/logger/xform_instance_parser.py @@ -366,10 +366,9 @@ def get_xform_media_question_xpaths( xform: 'onadata.apps.logger.models.XForm', ) -> list: logger = logging.getLogger('console_logger') - parser = XFormInstanceParser(xform.xml, xform.data_dictionary()) + parser = XFormInstanceParser(xform.xml, xform.data_dictionary(use_cache=True)) all_attributes = _get_all_attributes(parser.get_root_node()) media_field_xpaths = [] - # This code expects that the attributes from Enketo Express are **always** # sent in the same order. # For example: