Merge pull request #675 from grafana/matiasb/list-schedules-query-rework

Rework schedule escalation chains/policies count as a subquery
This commit is contained in:
Matias Bordese 2022-10-20 13:04:04 -03:00 committed by GitHub
commit f5896582ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 9 deletions

View file

@ -76,7 +76,8 @@ class ScheduleBaseSerializer(EagerLoadingMixin, serializers.ModelSerializer):
def get_number_of_escalation_chains(self, obj):
# num_escalation_chains param added in queryset via annotate. Check ScheduleView.get_queryset
# return 0 for just created schedules
return getattr(obj, "num_escalation_chains", 0)
num = getattr(obj, "num_escalation_chains", 0)
return num or 0
def validate(self, attrs):
if "slack_channel_id" in attrs:

View file

@ -13,7 +13,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.views import Response
from rest_framework.viewsets import ModelViewSet
from apps.alerts.models import EscalationChain
from apps.alerts.models import EscalationChain, EscalationPolicy
from apps.api.permissions import MODIFY_ACTIONS, READ_ACTIONS, ActionPermission, AnyRole, IsAdmin, IsAdminOrEditor
from apps.api.serializers.schedule_base import ScheduleFastSerializer
from apps.api.serializers.schedule_polymorphic import (
@ -108,22 +108,28 @@ class ScheduleView(
slack_team_identity=organization.slack_team_identity,
slack_id=OuterRef("channel"),
)
escalation_policies = (
EscalationPolicy.objects.values("notify_schedule")
.order_by("notify_schedule")
.annotate(num_escalation_chains=Count("notify_schedule"))
.filter(notify_schedule=OuterRef("id"))
)
queryset = queryset.annotate(
slack_channel_name=Subquery(slack_channels.values("name")[:1]),
slack_channel_pk=Subquery(slack_channels.values("public_primary_key")[:1]),
num_escalation_chains=Count(
"escalation_policies__escalation_chain",
distinct=True,
),
num_escalation_chains=Subquery(escalation_policies.values("num_escalation_chains")[:1]),
)
return queryset
def get_queryset(self):
is_short_request = self.request.query_params.get("short", "false") == "true"
organization = self.request.auth.organization
queryset = OnCallSchedule.objects.filter(
organization=organization,
team=self.request.user.current_team,
queryset = OnCallSchedule.objects.filter(organization=organization, team=self.request.user.current_team).defer(
# avoid requesting large text fields which are not used when listing schedules
"cached_ical_file_primary",
"prev_ical_file_primary",
"cached_ical_file_overrides",
"prev_ical_file_overrides",
)
if not is_short_request:
queryset = self._annotate_queryset(queryset)