Skip to content

Commit

Permalink
fixed n+1 queries
Browse files Browse the repository at this point in the history
  • Loading branch information
opaduchak committed Jan 6, 2025
1 parent 71a76c5 commit 8c6aea3
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 25 deletions.
11 changes: 10 additions & 1 deletion addon_service/addon_operation_invocation/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ class Meta:
thru_addon = CustomPolymorphicResourceRelatedField(
many=False,
required=False,
queryset=ConfiguredAddon.objects.active(),
queryset=ConfiguredAddon.objects.active().select_related(
"base_account__external_service",
"base_account__authorizedstorageaccount",
"base_account__authorizedcitationaccount",
"base_account__account_owner",
),
related_link_view_name=view_names.related_view(RESOURCE_TYPE),
polymorphic_serializer=ConfiguredAddonPolymorphicSerializer,
)
Expand All @@ -92,6 +97,10 @@ class Meta:
"by_user": "addon_service.serializers.UserReferenceSerializer",
}

def to_internal_value(self, data):
validated_data = super().to_internal_value(data)
return validated_data

def create(self, validated_data):
_thru_addon = validated_data.get("thru_addon")
_thru_account = validated_data.get("thru_account")
Expand Down
26 changes: 25 additions & 1 deletion addon_service/addon_operation_invocation/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,31 @@ def retrieve_related(self, request, *args, **kwargs):

def perform_create(self, serializer):
super().perform_create(serializer)
narrowed_down_types = (
[
"thru_addon__configuredcitationaddon",
"thru_addon__base_account__authorizedcitationaccount",
]
if "citation"
in serializer.initial_data.get(
"thru_addon", serializer.initial_data.get("thru_account")
)["type"]
else [
"thru_addon__configuredstorageaddon",
"thru_addon__base_account__authorizedstorageaccount",
]
)
# after creating the AddonOperationInvocation, look into invoking it
_invocation = serializer.instance
_invocation = (
AddonOperationInvocation.objects.filter(pk=serializer.instance.pk)
.select_related(
"thru_addon__base_account__external_service",
*narrowed_down_types,
"thru_addon__base_account___credentials",
"thru_account___credentials",
)
.first()
)
_operation_type = _invocation.operation.operation_type
match _operation_type:
case AddonOperationType.REDIRECT | AddonOperationType.IMMEDIATE:
Expand All @@ -96,3 +119,4 @@ def perform_create(self, serializer):
perform_invocation__celery.delay(_invocation.pk)
case _:
raise ValueError(f"unknown operation type: {_operation_type}")
serializer.instance = _invocation
2 changes: 2 additions & 0 deletions addon_service/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class GVCombinedAuthentication(drf_authentication.BaseAuthentication):
"""Authentication supporting session, basic, and token methods."""

def authenticate(self, request: DrfRequest):
if request.session.get("user_reference_uri"):
return True, None
_user_uri = osf.get_osf_user_uri(request)
if _user_uri:
UserReference.objects.get_or_create(user_uri=_user_uri)
Expand Down
29 changes: 17 additions & 12 deletions addon_service/common/serializer_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
SkipDataMixin,
)

from addon_service.authorized_account.models import AuthorizedAccount
from addon_service.configured_addon.models import ConfiguredAddon


class ReadOnlyResourceRelatedField(
json_api_serializers.ResourceRelatedField, drf_serializers.ReadOnlyField
Expand Down Expand Up @@ -54,16 +57,18 @@ def get(self, *, pk):
class CustomPolymorphicResourceRelatedField(PolymorphicResourceRelatedField):
def to_representation(self, value):
data = super().to_representation(value)
if hasattr(value, "authorizedcitationaccount"):
data["type"] = "authorized-citation-accounts"
elif hasattr(value, "authorizedcomputingaccount"):
data["type"] = "authorized-computing-accounts"
elif hasattr(value, "authorizedstorageaccount"):
data["type"] = "authorized-storage-accounts"
elif hasattr(value, "configuredcitationaddon"):
data["type"] = "configured-citation-addons"
elif hasattr(value, "configuredcomputingaddon"):
data["type"] = "configured-computing-addons"
elif hasattr(value, "configuredstorageaccount"):
data["type"] = "configured-storage-addons"
if isinstance(value, AuthorizedAccount):
if hasattr(value, "authorizedcitationaccount"):
data["type"] = "authorized-citation-accounts"
elif hasattr(value, "authorizedstorageaccount"):
data["type"] = "authorized-storage-accounts"
elif hasattr(value, "authorizedcomputingaccount"):
data["type"] = "authorized-computing-accounts"
elif isinstance(value, ConfiguredAddon):
if hasattr(value, "configuredcitationaddon"):
data["type"] = "configured-citation-addons"
elif hasattr(value, "configuredstorageaddon"):
data["type"] = "configured-storage-addons"
elif hasattr(value, "configuredcomputingaddon"):
data["type"] = "configured-computing-addons"
return data
7 changes: 6 additions & 1 deletion addon_service/configured_addon/storage/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@


class ConfiguredStorageAddonViewSet(ConfiguredAddonViewSet):
queryset = ConfiguredStorageAddon.objects.active()
queryset = ConfiguredStorageAddon.objects.active().select_related(
"base_account__authorizedstorageaccount",
"base_account__account_owner",
"base_account__external_service__externalstorageservice",
"authorized_resource",
)
serializer_class = ConfiguredStorageAddonSerializer

@action(
Expand Down
4 changes: 3 additions & 1 deletion addon_service/external_service/citation/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@


class ExternalCitationServiceViewSet(ReadOnlyModelViewSet):
queryset = ExternalCitationService.objects.all()
queryset = ExternalCitationService.objects.all().select_related(
"oauth2_client_config", "oauth1_client_config"
)
serializer_class = ExternalCitationServiceSerializer
4 changes: 3 additions & 1 deletion addon_service/external_service/computing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@


class ExternalComputingServiceViewSet(ReadOnlyModelViewSet):
queryset = ExternalComputingService.objects.all()
queryset = ExternalComputingService.objects.all().select_related(
"oauth2_client_config"
)
serializer_class = ExternalComputingServiceSerializer
4 changes: 3 additions & 1 deletion addon_service/external_service/storage/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@


class ExternalStorageServiceViewSet(ReadOnlyModelViewSet):
queryset = ExternalStorageService.objects.all()
queryset = ExternalStorageService.objects.all().select_related(
"oauth2_client_config"
)
serializer_class = ExternalStorageServiceSerializer
26 changes: 22 additions & 4 deletions addon_service/resource_reference/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,35 @@ class ResourceReference(AddonsServiceBaseModel):

@property
def configured_storage_addons(self):
return ConfiguredStorageAddon.objects.filter(authorized_resource=self).order_by(
Lower("_display_name")
return (
ConfiguredStorageAddon.objects.filter(authorized_resource=self)
.select_related(
"base_account__external_service__externalstorageservice",
"base_account__authorizedstorageaccount",
"base_account__account_owner",
)
.order_by(Lower("_display_name"))
)

@property
def configured_citation_addons(self):
return ConfiguredCitationAddon.objects.filter(authorized_resource=self)
return ConfiguredCitationAddon.objects.filter(
authorized_resource=self
).select_related(
"base_account__external_service__externalcitationservice",
"base_account__authorizedcitationaccount",
"base_account__account_owner",
)

@property
def configured_computing_addons(self):
return ConfiguredComputingAddon.objects.filter(authorized_resource=self)
return ConfiguredComputingAddon.objects.filter(
authorized_resource=self
).select_related(
"base_account__external_service__externalcomputingservice",
"base_account__authorizedcitationaccount",
"base_account__account_owner",
)

class Meta:
verbose_name = "Resource Reference"
Expand Down
12 changes: 9 additions & 3 deletions addon_service/user_reference/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ def configured_resources(self):

@property
def authorized_storage_accounts(self):
return AuthorizedStorageAccount.objects.filter(account_owner=self)
return AuthorizedStorageAccount.objects.filter(
account_owner=self
).select_related("external_service")

@property
def authorized_citation_accounts(self):
return AuthorizedCitationAccount.objects.filter(account_owner=self)
return AuthorizedCitationAccount.objects.filter(
account_owner=self
).select_related("external_service")

@property
def authorized_computing_accounts(self):
return AuthorizedComputingAccount.objects.filter(account_owner=self)
return AuthorizedComputingAccount.objects.filter(
account_owner=self
).select_related("external_service")

class Meta:
verbose_name = "User Reference"
Expand Down

0 comments on commit 8c6aea3

Please sign in to comment.