separate-getter
All checks were successful
Deploy to core / deploy (push) Successful in 1m53s

This commit is contained in:
Untone 2024-02-23 02:49:34 +03:00
parent 3d34c6c540
commit 392cfb19bd
4 changed files with 63 additions and 49 deletions

View File

@ -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 add_stat_columns, get_with_stat, unpack_stat
from resolvers.stat import get_authors_with_stat
from services.auth import login_required
from services.db import local_session
from services.rediscache import redis
@ -98,7 +98,7 @@ def count_author_shouts_rating(session, author_id) -> int:
def load_author_with_stats(q):
result = get_with_stat(q, Author, AuthorFollower)
result = get_authors_with_stat(q)
if result:
[author] = result
@ -199,7 +199,7 @@ def load_authors_by(_, _info, by, limit, offset):
q = q.limit(limit).offset(offset)
q = q.group_by(Author.id)
authors = get_with_stat(q, Author, AuthorFollower)
authors = get_authors_with_stat(q)
return authors
@ -269,14 +269,10 @@ def create_author(user_id: str, slug: str, name: str = ''):
@query.field('get_author_followers')
def get_author_followers(_, _info, slug) -> List[Author]:
aliased_author = aliased(Author)
q = select(aliased_author)
q = select(Author)
q = (
q.join(AuthorFollower, AuthorFollower.follower == Author.id)
.join(aliased_author, aliased_author.id == AuthorFollower.author)
.where(aliased_author.slug == slug)
.join(Author, Author.id == AuthorFollower.author)
.where(Author.slug == slug)
)
q = add_stat_columns(q, aliased_author, AuthorFollower)
q = q.group_by(aliased_author.id)
return unpack_stat(q)
return get_authors_with_stat(q)

View File

@ -14,7 +14,7 @@ from orm.shout import Shout, ShoutReactionsFollower
from orm.topic import Topic, TopicFollower
from resolvers.community import community_follow, community_unfollow
from resolvers.topic import topic_follow, topic_unfollow
from resolvers.stat import add_stat_columns, unpack_stat
from resolvers.stat import get_topics_with_stat, get_authors_with_stat
from services.auth import login_required
from services.db import local_session
from services.follows import DEFAULT_FOLLOWS
@ -110,10 +110,8 @@ def query_follows(user_id: str):
.filter(TopicFollower.topic == Topic.id)
)
authors_query = add_stat_columns(authors_query, aliased_author, AuthorFollower)
authors = unpack_stat(authors_query)
topics_query = add_stat_columns(topics_query, aliased_author, TopicFollower)
authors = unpack_stat(topics_query)
authors = get_authors_with_stat(authors_query)
topics = get_topics_with_stat(topics_query)
return {
'topics': topics,
@ -226,10 +224,7 @@ def get_topic_followers(_, _info, slug: str, topic_id: int) -> List[Author]:
.join(Topic, Topic.id == TopicFollower.topic)
.filter(or_(Topic.slug == slug, Topic.id == topic_id))
)
q = add_stat_columns(q, Author, TopicFollower)
q = q.group_by(Author.id)
return unpack_stat(q)
return get_authors_with_stat(q)
@query.field('get_shout_followers')

View File

@ -1,19 +1,44 @@
from sqlalchemy import func, distinct
from sqlalchemy.orm import aliased
from orm.topic import TopicFollower, Topic
from services.db import local_session
from orm.author import AuthorFollower
from orm.author import AuthorFollower, Author
from orm.shout import ShoutTopic, ShoutAuthor
def add_stat_columns(q, author_alias, follower_model_alias):
shouts_stat_model = ShoutAuthor if isinstance(follower_model_alias, AuthorFollower) else ShoutTopic
q = q.outerjoin(shouts_stat_model).add_columns(func.count(distinct(shouts_stat_model.shout)).label('shouts_stat'))
q = q.outerjoin(
follower_model_alias, follower_model_alias.follower == author_alias.id
).add_columns(func.count(distinct(follower_model_alias.author)).label('authors_stat'))
q = q.outerjoin(follower_model_alias, follower_model_alias.author == author_alias.id).add_columns(
func.count(distinct(follower_model_alias.follower)).label('followers_stat')
def add_topic_stat_columns(q):
aliased_shout_author = aliased(ShoutAuthor)
aliased_topic_follower = aliased(TopicFollower)
q = (
q.outerjoin(ShoutTopic, 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)
.add_columns(func.count(distinct(aliased_topic_follower.follower)).label('followers_stat'))
)
q = q.group_by(Topic.id)
return q
def add_author_stat_columns(q):
aliased_author_followers = aliased(AuthorFollower)
aliased_author_authors = aliased(AuthorFollower)
q = (
q.outerjoin(ShoutAuthor, Author.id == ShoutAuthor.author)
.add_columns(func.count(distinct(ShoutAuthor.shout)).label('shouts_stat'))
.outerjoin(aliased_author_authors, AuthorFollower.follower == Author.id)
.add_columns(func.count(distinct(aliased_author_authors.author)).label('authors_stat'))
.outerjoin(aliased_author_followers)
.add_columns(func.count(distinct(aliased_author_followers.follower)).label('followers_stat'))
)
q = q.group_by(Author.id)
return q
@ -31,6 +56,11 @@ def unpack_stat(q):
return records
def get_with_stat(q, author_alias, follower_model_alias):
q = add_stat_columns(q, author_alias, follower_model_alias)
def get_authors_with_stat(q):
q = add_author_stat_columns(q)
return unpack_stat(q)
def get_topics_with_stat(q):
q = add_topic_stat_columns(q)
return unpack_stat(q)

View File

@ -3,7 +3,7 @@ from sqlalchemy import and_, distinct, func, select
from orm.author import Author
from orm.shout import ShoutTopic
from orm.topic import Topic, TopicFollower
from resolvers.stat import get_with_stat
from resolvers.stat import get_topics_with_stat
from services.auth import login_required
from services.db import local_session
from services.schema import mutation, query
@ -12,22 +12,17 @@ from services.logger import root_logger as logger
@query.field('get_topics_all')
def get_topics_all(_, _info):
q = select(Topic)
q = q.group_by(Topic.id)
topics = get_with_stat(q, Author, TopicFollower)
return topics
return get_topics_with_stat(select(Topic))
@query.field('get_topics_by_community')
async def get_topics_by_community(_, _info, community_id: int):
def get_topics_by_community(_, _info, community_id: int):
q = select(Topic).where(Topic.community == community_id)
q = q.group_by(Topic.id)
topics = await get_with_stat(q, Author, TopicFollower)
return topics
return get_topics_with_stat(q)
@query.field('get_topics_by_author')
async def get_topics_by_author(_, _info, author_id=None, slug='', user=''):
def get_topics_by_author(_, _info, author_id=None, slug='', user=''):
q = select(Topic)
if author_id:
q = q.join(Author).where(Author.id == author_id)
@ -36,23 +31,21 @@ async def get_topics_by_author(_, _info, author_id=None, slug='', user=''):
elif user:
q = q.join(Author).where(Author.user == user)
q = q.group_by(Topic.id)
topics = await get_with_stat(q, Author, TopicFollower)
return topics
return get_topics_with_stat(q)
@query.field('get_topic')
async def get_topic(_, _info, slug):
def get_topic(_, _info, slug):
q = select(Topic).filter(Topic.slug == slug)
q = q.group_by(Topic.id)
topics = await get_with_stat(q, Author, TopicFollower)
topics = get_topics_with_stat(q)
if topics:
return topics[0]
@mutation.field('create_topic')
@login_required
async def create_topic(_, _info, inp):
def create_topic(_, _info, inp):
with local_session() as session:
# TODO: check user permissions to create topic for exact community
# and actor is permitted to craete it
@ -65,7 +58,7 @@ async def create_topic(_, _info, inp):
@mutation.field('update_topic')
@login_required
async def update_topic(_, _info, inp):
def update_topic(_, _info, inp):
slug = inp['slug']
with local_session() as session:
topic = session.query(Topic).filter(Topic.slug == slug).first()
@ -81,7 +74,7 @@ async def update_topic(_, _info, inp):
@mutation.field('delete_topic')
@login_required
async def delete_topic(_, info, slug: str):
def delete_topic(_, info, slug: str):
user_id = info.context['user_id']
with local_session() as session:
t: Topic = session.query(Topic).filter(Topic.slug == slug).first()