Skip to content

Commit 74a16c2

Browse files
committed
temp
1 parent 655ace0 commit 74a16c2

1 file changed

Lines changed: 32 additions & 7 deletions

File tree

pulpcore/app/models/repository.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
get_prn,
2626
get_view_name_for_model,
2727
reverse,
28-
safe_in,
2928
)
3029
from pulpcore.cache import Cache
3130
from pulpcore.constants import ALL_KNOWN_CONTENT_CHECKSUMS, PROTECTED_REPO_VERSION_MESSAGE
@@ -909,6 +908,19 @@ def with_content(self, content):
909908
return self.filter(content_ids__overlap=content_pks)
910909

911910

911+
class RepositoryVersionManager(models.Manager):
912+
"""Manager that defers the content_ids array column by default.
913+
914+
The content_ids array can be very large and is expensive to transfer from
915+
PostgreSQL to Python. Most queries don't need it — callers that do
916+
(add_content, remove_content, set_content_ids, etc.) access it through
917+
the model instance which triggers a deferred-field load automatically.
918+
"""
919+
920+
def get_queryset(self):
921+
return RepositoryVersionQuerySet(self.model, using=self._db).defer("content_ids")
922+
923+
912924
class RepositoryVersion(BaseModel):
913925
"""
914926
A version of a repository's content set.
@@ -937,7 +949,7 @@ class RepositoryVersion(BaseModel):
937949
base_version (models.ForeignKey): The repository version this was created from.
938950
"""
939951

940-
objects = RepositoryVersionQuerySet.as_manager()
952+
objects = RepositoryVersionManager()
941953

942954
repository = models.ForeignKey(Repository, on_delete=models.CASCADE)
943955
number = models.PositiveIntegerField(db_index=True)
@@ -975,6 +987,19 @@ def set_content_ids(self):
975987
else:
976988
self.content_ids = previous.content_ids
977989

990+
def _content_ids_subquery(self):
991+
"""Return a subquery that unnests content_ids server-side.
992+
993+
Keeps the array data inside PostgreSQL, avoiding the round-trip of
994+
loading a potentially huge list into Python and sending it back as
995+
query parameters.
996+
"""
997+
return (
998+
RepositoryVersion.objects.filter(pk=self.pk)
999+
.annotate(cids=Func(F("content_ids"), function="unnest"))
1000+
.values_list("cids", flat=True)
1001+
)
1002+
9781003
def get_content(self, content_qs=None):
9791004
"""
9801005
Returns a set of content for a repository version
@@ -998,7 +1023,7 @@ def get_content(self, content_qs=None):
9981023
if content_qs is None:
9991024
content_qs = Content.objects
10001025

1001-
return content_qs.filter(safe_in("pk", self.content_ids))
1026+
return content_qs.filter(pk__in=self._content_ids_subquery())
10021027

10031028
@property
10041029
def content(self):
@@ -1112,8 +1137,8 @@ def added(self, base_version=None):
11121137
if not base_version:
11131138
return Content.objects.filter(version_memberships__version_added=self)
11141139

1115-
return Content.objects.filter(safe_in("pk", self.content_ids)).exclude(
1116-
safe_in("pk", base_version.content_ids)
1140+
return Content.objects.filter(pk__in=self._content_ids_subquery()).exclude(
1141+
pk__in=base_version._content_ids_subquery()
11171142
)
11181143

11191144
def removed(self, base_version=None):
@@ -1127,8 +1152,8 @@ def removed(self, base_version=None):
11271152
if not base_version:
11281153
return Content.objects.filter(version_memberships__version_removed=self)
11291154

1130-
return Content.objects.filter(safe_in("pk", base_version.content_ids)).exclude(
1131-
safe_in("pk", self.content_ids)
1155+
return Content.objects.filter(pk__in=base_version._content_ids_subquery()).exclude(
1156+
pk__in=self._content_ids_subquery()
11321157
)
11331158

11341159
def contains(self, content):

0 commit comments

Comments
 (0)