Skip to content

Commit

Permalink
Optimize unpaginated collection_versions endpoint query
Browse files Browse the repository at this point in the history
[noissue]
  • Loading branch information
gerrod3 committed May 4, 2021
1 parent 9cfa8cd commit 2291b95
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
5 changes: 4 additions & 1 deletion pulp_ansible/app/galaxy/v3/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ def get_artifact(self, obj):
"""
Get atrifact summary.
"""
ca = getattr(obj, "contentartifact", None)
if ca:
return ArtifactRefSerializer(ca).data
return ArtifactRefSerializer(obj.contentartifact_set.get()).data

def get_download_url(self, obj) -> str:
Expand All @@ -206,7 +209,7 @@ def get_download_url(self, obj) -> str:
"""
host = settings.ANSIBLE_CONTENT_HOSTNAME.strip("/")
distro_base_path = self.context["path"]
filename_path = obj.contentartifact_set.get().relative_path.lstrip("/")
filename_path = obj.relative_path.lstrip("/")
download_url = f"{host}/{distro_base_path}/{filename_path}"
return download_url

Expand Down
56 changes: 46 additions & 10 deletions pulp_ansible/app/galaxy/v3/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from gettext import gettext as _
import semantic_version

from collections import namedtuple
from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import F
from django.db.models.expressions import Window
Expand Down Expand Up @@ -422,6 +423,10 @@ def list(self, request, *args, **kwargs):
return Response(serializer.data)


ContentArtifact = namedtuple("ContentArtifact", ("relative_path", "artifact"))
Artifact = namedtuple("Artifact", ("sha256", "size"))


class UnpaginatedCollectionVersionViewSet(CollectionVersionViewSet):
"""Unpaginated ViewSet for CollectionVersions."""

Expand All @@ -434,24 +439,55 @@ def get_queryset(self):
"""
distro_content = self._distro_content

return CollectionVersion.objects.select_related("content_ptr__contentartifact").filter(
pk__in=distro_content
return CollectionVersion.objects.filter(pk__in=distro_content).values(
"pk",
"name",
"namespace",
"version",
"requires_ansible",
"authors",
"contents",
"dependencies",
"description",
"documentation",
"homepage",
"issues",
"license",
"repository",
"collection_id",
"collection__pulp_created",
"collection__pulp_last_updated",
"contentartifact__artifact__sha256",
"contentartifact__artifact__size",
)

@staticmethod
def construct_full_collection_version(obj):
"""Constructs a new CollectionVersion object."""
collection_attrs = {
"pk": obj["collection_id"],
"pulp_created": obj.pop("collection__pulp_created"),
"pulp_last_updated": obj.pop("collection__pulp_last_updated"),
"name": obj["name"],
"namespace": obj["namespace"],
}
collection = Collection(**collection_attrs)
artifact = Artifact(
obj.pop("contentartifact__artifact__sha256"), obj.pop("contentartifact__artifact__size")
)
collection_version = CollectionVersion(**obj)
setattr(collection_version, "collection", collection)
content_artifact = ContentArtifact(collection_version.relative_path, artifact)
setattr(collection_version, "contentartifact", content_artifact)
return collection_version

def list(self, request, *args, **kwargs):
"""
Returns paginated CollectionVersions list.
"""
queryset = self.filter_queryset(self.get_queryset())
queryset = sorted(
queryset, key=lambda obj: semantic_version.Version(obj.version), reverse=True
)
queryset = map(self.construct_full_collection_version, self.get_queryset().iterator())

context = self.get_serializer_context()
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True, context=context)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True, context=context)
return Response(serializer.data)
Expand Down

0 comments on commit 2291b95

Please sign in to comment.