From 1295144681c26a7ad99bc652271cfd957c8b427d Mon Sep 17 00:00:00 2001 From: Agate Date: Thu, 9 Jul 2020 11:51:58 +0200 Subject: [PATCH] Fixed really slow SQL --- api/funkwhale_api/manage/serializers.py | 4 ++++ api/funkwhale_api/manage/views.py | 2 +- api/funkwhale_api/music/serializers.py | 4 ++-- api/funkwhale_api/music/views.py | 16 +++++++++------- api/tests/manage/test_serializers.py | 3 ++- front/src/views/admin/library/AlbumDetail.vue | 2 +- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/api/funkwhale_api/manage/serializers.py b/api/funkwhale_api/manage/serializers.py index d8cab9731..de7d7d63b 100644 --- a/api/funkwhale_api/manage/serializers.py +++ b/api/funkwhale_api/manage/serializers.py @@ -443,8 +443,12 @@ class ManageAlbumSerializer( "artist", "attributed_to", "tags", + "tracks_count", ] + def get_tracks_count(self, o): + return len(o.tracks.all()) + def get_tags(self, obj): tagged_items = getattr(obj, "_prefetched_tagged_items", []) return [ti.tag.name for ti in tagged_items] diff --git a/api/funkwhale_api/manage/views.py b/api/funkwhale_api/manage/views.py index bc3908dae..52bdfaf24 100644 --- a/api/funkwhale_api/manage/views.py +++ b/api/funkwhale_api/manage/views.py @@ -128,7 +128,7 @@ class ManageAlbumViewSet( music_models.Album.objects.all() .order_by("-id") .select_related("attributed_to", "artist", "attachment_cover") - .with_tracks_count() + .prefetch_related("tracks") ) serializer_class = serializers.ManageAlbumSerializer filterset_class = filters.ManageAlbumFilterSet diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py index 7dfef3bca..7d894b5ed 100644 --- a/api/funkwhale_api/music/serializers.py +++ b/api/funkwhale_api/music/serializers.py @@ -101,7 +101,7 @@ class ArtistAlbumSerializer(serializers.Serializer): return o.artist_id def get_tracks_count(self, o): - return o._tracks_count + return len(o.tracks.all()) def get_is_playable(self, obj): try: @@ -210,7 +210,7 @@ class AlbumSerializer(OptionalDescriptionMixin, serializers.Serializer): return serialize_artist_simple(o.artist) def get_tracks_count(self, o): - return getattr(o, "_tracks_count", None) + return len(o.tracks.all()) def get_is_playable(self, obj): try: diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index 5a4e81da4..2b4af7ae6 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -152,8 +152,10 @@ class ArtistViewSet( def get_queryset(self): queryset = super().get_queryset() - albums = models.Album.objects.with_tracks_count().select_related( - "attachment_cover" + albums = ( + models.Album.objects.with_tracks_count() + .select_related("attachment_cover") + .prefetch_related("tracks") ) albums = albums.annotate_playable_by_actor( utils.get_actor_from_request(self.request) @@ -179,10 +181,10 @@ class AlbumViewSet( viewsets.ReadOnlyModelViewSet, ): queryset = ( - models.Album.objects.all() - .order_by("-creation_date") - .with_tracks_count() - .prefetch_related("artist", "attributed_to", "attachment_cover") + models.Album.objects.all().order_by("-creation_date") + # we do a prefetech related on tracks instead of a count because it's more efficient + # db-wise + .prefetch_related("artist", "attributed_to", "attachment_cover", "tracks") ) serializer_class = serializers.AlbumSerializer permission_classes = [oauth_permissions.ScopePermission] @@ -759,7 +761,7 @@ class Search(views.APIView): "album", queryset=models.Album.objects.select_related( "artist", "attachment_cover", "attributed_to" - ), + ).prefetch_related("tracks"), ), ) ) diff --git a/api/tests/manage/test_serializers.py b/api/tests/manage/test_serializers.py index d6de65a47..6ba29897e 100644 --- a/api/tests/manage/test_serializers.py +++ b/api/tests/manage/test_serializers.py @@ -373,6 +373,7 @@ def test_manage_nested_artist_serializer(factories, now, to_api_date): def test_manage_album_serializer(factories, now, to_api_date): album = factories["music.Album"](attributed=True, with_cover=True) + factories["music.Track"](album=album) setattr(album, "_tracks_count", 42) expected = { "id": album.id, @@ -389,7 +390,7 @@ def test_manage_album_serializer(factories, now, to_api_date): album.attributed_to ).data, "tags": [], - "tracks_count": 42, + "tracks_count": 1, } s = serializers.ManageAlbumSerializer(album) diff --git a/front/src/views/admin/library/AlbumDetail.vue b/front/src/views/admin/library/AlbumDetail.vue index d1a07da37..8f1060073 100644 --- a/front/src/views/admin/library/AlbumDetail.vue +++ b/front/src/views/admin/library/AlbumDetail.vue @@ -276,7 +276,7 @@ - {{ object.tracks.length }} + {{ object.tracks_count }}