This commit is contained in:
Untone 2024-02-23 04:08:29 +03:00
parent ef7f2d7b92
commit 6ed09d5851
3 changed files with 39 additions and 20 deletions

View File

@ -10,7 +10,7 @@ from orm.reaction import Reaction, ReactionKind
from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutTopic
from orm.topic import Topic from orm.topic import Topic
from resolvers.follower import query_follows from resolvers.follower import query_follows
from resolvers.stat import get_authors_with_stat, unpack_stat from resolvers.stat import get_authors_with_stat, execute_with_ministat
from services.auth import login_required from services.auth import login_required
from services.db import local_session from services.db import local_session
from services.rediscache import redis from services.rediscache import redis
@ -295,4 +295,4 @@ def get_author_followers(_, _info, slug):
.group_by(author_alias.id) .group_by(author_alias.id)
) )
return unpack_stat(q) return execute_with_ministat(q)

View File

@ -2,7 +2,7 @@ import json
import time import time
from typing import List from typing import List
from sqlalchemy import select, or_ from sqlalchemy import select, or_, func
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
from sqlalchemy.sql import and_ from sqlalchemy.sql import and_
@ -10,11 +10,11 @@ from orm.author import Author, AuthorFollower
# from orm.community import Community # from orm.community import Community
from orm.reaction import Reaction from orm.reaction import Reaction
from orm.shout import Shout, ShoutReactionsFollower from orm.shout import Shout, ShoutReactionsFollower, ShoutAuthor, ShoutTopic
from orm.topic import Topic, TopicFollower from orm.topic import Topic, TopicFollower
from resolvers.community import community_follow, community_unfollow from resolvers.community import community_follow, community_unfollow
from resolvers.topic import topic_follow, topic_unfollow from resolvers.topic import topic_follow, topic_unfollow
from resolvers.stat import get_topics_with_stat, get_authors_with_stat from resolvers.stat import get_authors_with_stat
from services.auth import login_required from services.auth import login_required
from services.db import local_session from services.db import local_session
from services.follows import DEFAULT_FOLLOWS from services.follows import DEFAULT_FOLLOWS
@ -95,23 +95,42 @@ def query_follows(user_id: str):
if isinstance(author, Author): if isinstance(author, Author):
author_id = author.id author_id = author.id
aliased_author = aliased(Author) aliased_author = aliased(Author)
aliased_author_followers = aliased(AuthorFollower)
aliased_author_authors = aliased(AuthorFollower)
authors_query = ( authors = (
session.query(aliased_author, AuthorFollower) session.query(
.select_from(aliased_author) # явное указание FROM-запроса aliased_author,
.join(AuthorFollower, AuthorFollower.follower == author_id) func.count(func.distinct(ShoutAuthor.shout)).label("shouts_stat"),
func.count(func.distinct(AuthorFollower.author)).label("authors_stat"),
func.count(func.distinct(AuthorFollower.follower)).label("followers_stat")
)
.filter(AuthorFollower.author == aliased_author.id) .filter(AuthorFollower.author == aliased_author.id)
.join(AuthorFollower, AuthorFollower.follower == aliased_author.id)
.outerjoin(ShoutAuthor, ShoutAuthor.author == author_id)
.outerjoin(aliased_author_authors, AuthorFollower.follower == author_id)
.outerjoin(aliased_author_followers, AuthorFollower.author == author_id)
.group_by(aliased_author.id)
.all()
) )
topics_query = ( aliased_shout_authors = aliased(ShoutAuthor)
session.query(Topic, TopicFollower) aliased_topic_followers = aliased(TopicFollower)
.select_from(Topic) # явное указание FROM-запроса aliased_topic = aliased(Topic)
.join(TopicFollower, TopicFollower.follower == author_id) topics = (
.filter(TopicFollower.topic == Topic.id) session.query(
aliased_topic,
func.count(func.distinct(ShoutTopic.shout)).label("shouts_stat"),
func.count(func.distinct(ShoutAuthor.author)).label("authors_stat"),
func.count(func.distinct(TopicFollower.follower)).label("followers_stat")
)
.join(TopicFollower, TopicFollower.topic == aliased_topic.id)
.outerjoin(ShoutTopic, aliased_topic.id == ShoutTopic.topic)
.outerjoin(aliased_shout_authors, ShoutTopic.shout == aliased_shout_authors.shout)
.outerjoin(aliased_topic_followers, aliased_topic_followers.topic == aliased_topic.id)
.group_by(aliased_topic.id)
.all()
) )
authors = get_authors_with_stat(authors_query)
topics = get_topics_with_stat(topics_query)
return { return {
'topics': topics, 'topics': topics,

View File

@ -43,7 +43,7 @@ def add_author_stat_columns(q):
return q return q
def unpack_stat(q): def execute_with_ministat(q):
records = [] records = []
with local_session() as session: with local_session() as session:
for [entity, shouts_stat, authors_stat, followers_stat] in session.execute(q): for [entity, shouts_stat, authors_stat, followers_stat] in session.execute(q):
@ -59,9 +59,9 @@ def unpack_stat(q):
def get_authors_with_stat(q): def get_authors_with_stat(q):
q = add_author_stat_columns(q) q = add_author_stat_columns(q)
return unpack_stat(q) return execute_with_ministat(q)
def get_topics_with_stat(q): def get_topics_with_stat(q):
q = add_topic_stat_columns(q) q = add_topic_stat_columns(q)
return unpack_stat(q) return execute_with_ministat(q)