Optimize competences queries

This commit is contained in:
Christian Cueni 2024-07-22 11:49:55 +02:00
parent 2d3234c7ce
commit 128c8da2e6
1 changed files with 27 additions and 23 deletions

View File

@ -1,10 +1,13 @@
from typing import List, Tuple from typing import List, Tuple
import graphene import graphene
import structlog
from wagtail.models import Page from wagtail.models import Page
from vbv_lernwelt.course.models import CourseCompletion, CourseCompletionStatus from vbv_lernwelt.course.models import CourseCompletion, CourseCompletionStatus
logger = structlog.get_logger(__name__)
class CompetencePerformanceStatisticsSummaryType(graphene.ObjectType): class CompetencePerformanceStatisticsSummaryType(graphene.ObjectType):
_id = graphene.ID(required=True) _id = graphene.ID(required=True)
@ -41,25 +44,23 @@ def competences(
completions = CourseCompletion.objects.filter( completions = CourseCompletion.objects.filter(
course_session_id__in=course_session_selection_ids, course_session_id__in=course_session_selection_ids,
page_type="competence.PerformanceCriteria", page_type="competence.PerformanceCriteria",
).prefetch_related("course_session", "page") ).select_related("course_session", "page")
if user_selection_ids is not None: if user_selection_ids is not None:
completions = completions.filter(user_id__in=user_selection_ids) completions = completions.filter(user_id__in=user_selection_ids)
competence_records = {} page_ids = completions.values_list("page_id", flat=True).distinct()
pages = Page.objects.filter(id__in=page_ids)
learning_units = {page.id: page.specific.learning_unit for page in pages}
unique_page_ids = {completion.page.id for completion in completions}
learning_units = {
page_id: Page.objects.get(id=page_id).specific.learning_unit
for page_id in unique_page_ids
}
circles = { circles = {
lu.id: c lu.id: c
for lu in learning_units.values() for lu in learning_units.values()
if (lu is not None and (c := lu.get_circle()) is not None) if lu and (c := lu.get_circle()) and (circle_ids is None or c.id in circle_ids)
and (circle_ids is None or c.id in circle_ids)
} }
competence_records = {}
for completion in completions: for completion in completions:
learning_unit = learning_units.get(completion.page.id) learning_unit = learning_units.get(completion.page.id)
@ -73,20 +74,23 @@ def competences(
combined_id = f"{circle.id}-{completion.course_session.id}@{urql_id_postfix}" combined_id = f"{circle.id}-{completion.course_session.id}@{urql_id_postfix}"
competence_records.setdefault(combined_id, {}).setdefault( if combined_id not in competence_records:
learning_unit, competence_records[combined_id] = {}
CompetenceRecordStatisticsType(
_id=combined_id, # noqa if learning_unit not in competence_records[combined_id]:
title=learning_unit.title, # noqa competence_records[combined_id][
course_session_id=completion.course_session.id, # noqa learning_unit
generation=completion.course_session.generation, # noqa ] = CompetenceRecordStatisticsType(
circle_id=circle.id, # noqa _id=combined_id,
success_count=0, # noqa title=learning_unit.title,
fail_count=0, # noqa course_session_id=completion.course_session.id,
generation=completion.course_session.generation,
circle_id=circle.id,
success_count=0,
fail_count=0,
details_url=f"/course/{course_slug}/cockpit?courseSessionId={completion.course_session.id}", details_url=f"/course/{course_slug}/cockpit?courseSessionId={completion.course_session.id}",
# noqa # noqa
), )
)
if completion.completion_status == CourseCompletionStatus.SUCCESS.value: if completion.completion_status == CourseCompletionStatus.SUCCESS.value:
competence_records[combined_id][learning_unit].success_count += 1 competence_records[combined_id][learning_unit].success_count += 1
@ -99,7 +103,7 @@ def competences(
for record in circle_records.values() for record in circle_records.values()
] ]
success_count = sum([c.success_count for c in values]) success_count = sum(c.success_count for c in values)
fail_count = sum([c.fail_count for c in values]) fail_count = sum(c.fail_count for c in values)
return values, success_count, fail_count return values, success_count, fail_count