Update random objects getter

This commit is contained in:
2022-01-01 12:37:22 +03:00
parent a58136c5c2
commit 4a78d4f987
7 changed files with 49 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
from app.models import Author
from app.services.common import TRGMSearchService
from app.services.common import TRGMSearchService, GetRandomService
GET_OBJECT_IDS_QUERY = """
@@ -41,3 +41,7 @@ class AuthorTGRMSearchService(TRGMSearchService):
MODEL_CLASS = Author
PREFETCH_RELATED = ["source", "annotations"]
GET_OBJECT_IDS_QUERY = GET_OBJECT_IDS_QUERY
class GetRandomAuthorService(GetRandomService):
MODEL_CLASS = Author

View File

@@ -4,7 +4,7 @@ from fastapi import HTTPException, status
from app.models import Book as BookDB, Author as AuthorDB
from app.services.common import TRGMSearchService
from app.services.common import TRGMSearchService, GetRandomService
from app.serializers.book import CreateBook, CreateRemoteBook
@@ -76,3 +76,7 @@ class BookCreator:
return await cls._create_book(data)
if isinstance(data, CreateRemoteBook):
return await cls._create_remote_book(data)
class GetRandomBookService(GetRandomService):
MODEL_CLASS = BookDB

View File

@@ -122,3 +122,31 @@ class TRGMSearchService(Generic[T]):
total=total,
params=params
)
GET_RANDOM_OBJECT_ID_QUERY = """
SELECT id FROM {table}
WHERE id >= RANDOM() * (SELECT MAX(id) FROM {table})
ORDER BY id LIMIT 1;
"""
class GetRandomService(Generic[T]):
MODEL_CLASS: Optional[T] = None
@classmethod
@property
def model(cls) -> T:
assert cls.MODEL_CLASS is not None, f"MODEL in {cls.__name__} don't set!"
return cls.MODEL_CLASS
@classmethod
@property
def database(cls) -> Database:
return cls.model.Meta.database
@classmethod
async def get_random_id(cls) -> int:
table_name = cls.model.Meta.tablename
query = GET_RANDOM_OBJECT_ID_QUERY.format(table=table_name)
return await cls.database.fetch_val(query)

View File

@@ -1,6 +1,6 @@
from app.models import Sequence
from app.services.common import TRGMSearchService
from app.services.common import TRGMSearchService, GetRandomService
GET_OBJECT_IDS_QUERY = """
@@ -33,3 +33,7 @@ class SequenceTGRMSearchService(TRGMSearchService):
MODEL_CLASS = Sequence
PREFETCH_RELATED = ["source"]
GET_OBJECT_IDS_QUERY = GET_OBJECT_IDS_QUERY
class GetRandomSequenceService(GetRandomService):
MODEL_CLASS = Sequence

View File

@@ -9,7 +9,7 @@ from app.utils.pagination import CustomPage
from app.models import Author as AuthorDB, AuthorAnnotation as AuthorAnnotationDB, Book as BookDB
from app.serializers.author import Author, CreateAuthor, UpdateAuthor, AuthorBook, TranslatedBook
from app.serializers.author_annotation import AuthorAnnotation
from app.services.author import AuthorTGRMSearchService
from app.services.author import AuthorTGRMSearchService, GetRandomAuthorService
from app.depends import check_token
@@ -42,9 +42,7 @@ async def create_author(data: CreateAuthor):
@author_router.get("/random", response_model=Author)
async def get_random_author():
author_ids: list[int] = await AuthorDB.objects.values_list("id", flatten=True)
author_id = random_choice(author_ids)
author_id = await GetRandomAuthorService.get_random_id()
return await AuthorDB.objects.prefetch_related(PREFETCH_RELATED).get(id=author_id)

View File

@@ -10,7 +10,7 @@ from app.utils.pagination import CustomPage
from app.models import Book as BookDB, Author as AuthorDB, BookAnnotation as BookAnnotationDB
from app.serializers.book import Book, RemoteBook, BookDetail, CreateBook, UpdateBook, CreateRemoteBook
from app.serializers.book_annotation import BookAnnotation
from app.services.book import BookTGRMSearchService, BookCreator
from app.services.book import BookTGRMSearchService, GetRandomBookService, BookCreator
from app.filters.book import get_book_filter
from app.depends import check_token
@@ -41,9 +41,7 @@ async def create_book(data: Union[CreateBook, CreateRemoteBook]):
@book_router.get("/random", response_model=BookDetail)
async def get_random_book():
book_ids: list[int] = await BookDB.objects.filter(is_deleted=False).values_list("id", flatten=True)
book_id = random_choice(book_ids)
book_id = await GetRandomBookService.get_random_id()
return await BookDB.objects.select_related(SELECT_RELATED_FIELDS).get(id=book_id)

View File

@@ -8,7 +8,7 @@ from app.utils.pagination import CustomPage
from app.models import Sequence as SequenceDB, Book as BookDB, BookSequences as BookSequencesDB
from app.serializers.sequence import Sequence, CreateSequence, Book as SequenceBook
from app.services.sequence import SequenceTGRMSearchService
from app.services.sequence import SequenceTGRMSearchService, GetRandomSequenceService
from app.depends import check_token
@@ -28,9 +28,7 @@ async def get_sequences():
@sequence_router.get("/random", response_model=Sequence)
async def get_random_sequence():
sequence_ids: list[int] = await SequenceDB.objects.values_list("id", flatten=True)
sequence_id = random_choice(sequence_ids)
sequence_id = await GetRandomSequenceService.get_random_id()
return await SequenceDB.objects.get(id=sequence_id)