Skip to content

Commit 7c3b937

Browse files
committed
Improve content_ids handling by defered loading
The array_field can be huge and most of the time we don't need the values in python. Some uses can even be handled by clever SQL without ever channelling all the data through the network.
1 parent 4f05456 commit 7c3b937

1 file changed

Lines changed: 14 additions & 16 deletions

File tree

pulpcore/app/models/repository.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,10 @@ class Meta:
885885
class RepositoryVersionQuerySet(models.QuerySet):
886886
"""A queryset that provides repository version filtering methods."""
887887

888+
def get_queryset(self):
889+
# Prevent the content_ids to be automatically hydrated.
890+
return super().get_queryset().defer("content_ids")
891+
888892
def complete(self):
889893
return self.filter(complete=True)
890894

@@ -997,15 +1001,13 @@ def get_content(self, content_qs=None):
9971001
if content_qs is None:
9981002
content_qs = Content.objects
9991003

1000-
content_ids = self.content_ids
1001-
if len(content_ids) >= 65535:
1002-
# Workaround for PostgreSQL's limit on the number of parameters in a query
1003-
content_ids = (
1004-
RepositoryVersion.objects.filter(pk=self.pk)
1005-
.annotate(cids=Func(F("content_ids"), function="unnest"))
1006-
.values_list("cids", flat=True)
1007-
)
1008-
return content_qs.filter(pk__in=content_ids)
1004+
# Try to not even attempt to evaluate the content_ids on the python side.
1005+
content_ids_subquery = (
1006+
RepositoryVersion.objects.filter(pk=self.pk)
1007+
.annotate(cids=Func(F("content_ids"), function="unnest"))
1008+
.values_list("cids", flat=True)
1009+
)
1010+
return content_qs.filter(pk__in=content_ids_subquery)
10091011

10101012
@property
10111013
def content(self):
@@ -1119,9 +1121,7 @@ def added(self, base_version=None):
11191121
if not base_version:
11201122
return Content.objects.filter(version_memberships__version_added=self)
11211123

1122-
return Content.objects.filter(pk__in=self.content_ids).exclude(
1123-
pk__in=base_version.content_ids
1124-
)
1124+
return Content.objects.filter(pk__in=self.content).exclude(pk__in=base_version.content)
11251125

11261126
def removed(self, base_version=None):
11271127
"""
@@ -1134,9 +1134,7 @@ def removed(self, base_version=None):
11341134
if not base_version:
11351135
return Content.objects.filter(version_memberships__version_removed=self)
11361136

1137-
return Content.objects.filter(pk__in=base_version.content_ids).exclude(
1138-
pk__in=self.content_ids
1139-
)
1137+
return Content.objects.filter(pk__in=base_version.content).exclude(pk__in=self.content)
11401138

11411139
def contains(self, content):
11421140
"""
@@ -1145,7 +1143,7 @@ def contains(self, content):
11451143
Returns:
11461144
bool: True if the repository version contains the content, False otherwise
11471145
"""
1148-
return content.pk in self.content_ids
1146+
return content.pk in self.content
11491147

11501148
def add_content(self, content):
11511149
"""

0 commit comments

Comments
 (0)