From ef7f2d7b92100f7abbff8b56c50b6fd2caa51662 Mon Sep 17 00:00:00 2001 From: Untone Date: Fri, 23 Feb 2024 03:28:46 +0300 Subject: [PATCH] aliasing --- resolvers/author.py | 36 ++++++++++++++++++++++++++++-------- resolvers/stat.py | 27 ++++++++++++++------------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/resolvers/author.py b/resolvers/author.py index 4a2efb5e..181e5c4a 100644 --- a/resolvers/author.py +++ b/resolvers/author.py @@ -2,7 +2,7 @@ import json import time from typing import List -from sqlalchemy import and_, desc, select, or_ +from sqlalchemy import and_, desc, select, or_, distinct, func from sqlalchemy.orm import aliased from orm.author import Author, AuthorFollower, AuthorRating @@ -10,7 +10,7 @@ from orm.reaction import Reaction, ReactionKind from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.topic import Topic from resolvers.follower import query_follows -from resolvers.stat import get_authors_with_stat +from resolvers.stat import get_authors_with_stat, unpack_stat from services.auth import login_required from services.db import local_session from services.rediscache import redis @@ -268,11 +268,31 @@ def create_author(user_id: str, slug: str, name: str = ''): @query.field('get_author_followers') -def get_author_followers(_, _info, slug) -> List[Author]: - q = select(Author) +def get_author_followers(_, _info, slug): + author_alias = aliased(Author) + author_follower_alias = aliased(AuthorFollower) + shout_author_alias = aliased(ShoutAuthor) + q = ( - q.join(AuthorFollower, AuthorFollower.follower == Author.id) - .join(Author, Author.id == AuthorFollower.author) - .where(Author.slug == slug) + select(author_alias) + .join(author_follower_alias, author_follower_alias.author == author_alias.id) + .join(Author, Author.id == author_follower_alias.follower) + .filter(author_alias.slug == slug) + .add_columns( + func.count(distinct(shout_author_alias.shout)).label('shouts_stat'), + func.count(distinct(author_follower_alias.author)).label('authors_stat'), + func.count(distinct(author_follower_alias.follower)).label('followers_stat') + ) + .outerjoin(shout_author_alias, author_alias.id == shout_author_alias.author) + .outerjoin( + aliased(AuthorFollower, name="author_follower_1"), + author_follower_alias.follower == author_alias.id + ) + .outerjoin( + aliased(AuthorFollower, name="author_follower_2"), + author_follower_alias.author == author_alias.id + ) + .group_by(author_alias.id) ) - return get_authors_with_stat(q) + + return unpack_stat(q) diff --git a/resolvers/stat.py b/resolvers/stat.py index a0ba1165..a6944490 100644 --- a/resolvers/stat.py +++ b/resolvers/stat.py @@ -8,19 +8,19 @@ from orm.shout import ShoutTopic, ShoutAuthor def add_topic_stat_columns(q): - aliased_shout_author = aliased(ShoutAuthor) - aliased_topic_follower = aliased(TopicFollower) - + aliased_shout_authors = aliased(ShoutAuthor) + aliased_topic_followers = aliased(TopicFollower) + aliased_topic = aliased(Topic) q = ( - q.outerjoin(ShoutTopic, Topic.id == ShoutTopic.topic) + q.outerjoin(ShoutTopic, aliased_topic.id == ShoutTopic.topic) .add_columns(func.count(distinct(ShoutTopic.shout)).label('shouts_stat')) - .outerjoin(aliased_shout_author, ShoutTopic.shout == aliased_shout_author.shout) - .add_columns(func.count(distinct(aliased_shout_author.author)).label('authors_stat')) - .outerjoin(aliased_topic_follower, aliased_topic_follower.topic == Topic.id) - .add_columns(func.count(distinct(aliased_topic_follower.follower)).label('followers_stat')) + .outerjoin(aliased_shout_authors, ShoutTopic.shout == aliased_shout_authors.shout) + .add_columns(func.count(distinct(aliased_shout_authors.author)).label('authors_stat')) + .outerjoin(aliased_topic_followers, aliased_topic_followers.topic == aliased_topic.id) + .add_columns(func.count(distinct(aliased_topic_followers.follower)).label('followers_stat')) ) - q = q.group_by(Topic.id) + q = q.group_by(aliased_topic.id) return q @@ -28,16 +28,17 @@ def add_topic_stat_columns(q): def add_author_stat_columns(q): aliased_author_followers = aliased(AuthorFollower) aliased_author_authors = aliased(AuthorFollower) + aliased_author = aliased(Author) q = ( - q.outerjoin(ShoutAuthor, Author.id == ShoutAuthor.author) + q.outerjoin(ShoutAuthor, aliased_author.id == ShoutAuthor.author) .add_columns(func.count(distinct(ShoutAuthor.shout)).label('shouts_stat')) - .outerjoin(aliased_author_authors, AuthorFollower.follower == Author.id) + .outerjoin(aliased_author_authors, AuthorFollower.follower == aliased_author.id) .add_columns(func.count(distinct(aliased_author_authors.author)).label('authors_stat')) - .outerjoin(aliased_author_followers, AuthorFollower.author == Author.id) + .outerjoin(aliased_author_followers, AuthorFollower.author == aliased_author.id) .add_columns(func.count(distinct(aliased_author_followers.follower)).label('followers_stat')) ) - q = q.group_by(Author.id) + q = q.group_by(aliased_author.id) return q