From ac1fc151ab5e2cce9fa3706771ab1b37d0ad269f Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 28 Feb 2024 18:11:51 +0300 Subject: [PATCH] random-topic-shouts-patch --- resolvers/reader.py | 36 ++++++++++++++++-------------------- resolvers/topic.py | 22 ++++++---------------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/resolvers/reader.py b/resolvers/reader.py index 9aa2cb5e..00edfc61 100644 --- a/resolvers/reader.py +++ b/resolvers/reader.py @@ -8,7 +8,7 @@ from orm.reaction import Reaction, ReactionKind from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.topic import Topic, TopicFollower from resolvers.reaction import add_reaction_stat_columns -from resolvers.topic import get_random_topic +from resolvers.topic import random_topic_query from services.auth import login_required from services.db import local_session from services.schema import query @@ -461,36 +461,32 @@ async def load_shouts_random_top(_, _info, options): @query.field('load_shouts_random_topic') async def load_shouts_random_topic(_, info, limit: int = 10): - topic = get_random_topic() - if topic: - shouts = fetch_shouts_by_topic(topic, limit) - if shouts: - return {'topic': topic, 'shouts': shouts} - return { - 'error': 'failed to get random topic after few retries', - 'shouts': [], - 'topic': {}, - } - - -def fetch_shouts_by_topic(topic, limit): + random_topic_subquery = random_topic_query(1) q = ( - select(Shout) - .options(joinedload(Shout.authors), joinedload(Shout.topics)) + select(Shout, Topic) + .join(Shout.topics) + .join(random_topic_subquery, Topic.id == random_topic_subquery.id) + .options(joinedload(Shout.authors)) .filter( and_( Shout.deleted_at.is_(None), Shout.featured_at.is_not(None), - Shout.topics.any(slug=topic.slug), + Shout.topics.any(slug=Topic.slug), ) ) ) aliased_reaction = aliased(Reaction) q = add_reaction_stat_columns(q, aliased_reaction) - q = q.group_by(Shout.id).order_by(desc(Shout.created_at)).limit(limit) + result = local_session().execute(q) - shouts = get_shouts_from_query(q) + if result: + topic, shouts = result[0] + return {'topic': topic, 'shouts': shouts} - return shouts + return { + 'error': 'failed to get random topic after few retries', + 'shouts': [], + 'topic': None + } diff --git a/resolvers/topic.py b/resolvers/topic.py index 3c712eb6..64ce81da 100644 --- a/resolvers/topic.py +++ b/resolvers/topic.py @@ -121,12 +121,8 @@ def topic_unfollow(follower_id, slug): @query.field('get_topics_random') -async def get_topics_random(_, info, amount=12): - q = select(Topic) - q = q.join(ShoutTopic) - q = q.group_by(Topic.id) - q = q.having(func.count(distinct(ShoutTopic.shout)) > 2) - q = q.order_by(func.random()).limit(amount) +def get_topics_random(_, _info, amount=12): + q = random_topic_query(amount) topics = [] with local_session() as session: @@ -136,16 +132,10 @@ async def get_topics_random(_, info, amount=12): return topics -def get_random_topic(): +def random_topic_query(amount: int): q = select(Topic) q = q.join(ShoutTopic) q = q.group_by(Topic.id) - q = q.having(func.count(distinct(ShoutTopic.shout)) > 10) - q = q.order_by(func.random()).limit(1) - - with local_session() as session: - r = session.execute(q).first() - if r: - [topic] = r - return topic - return + q = q.having(func.count(distinct(ShoutTopic.shout)) > 2) + q = q.order_by(func.random()).limit(amount) + return q