follower-stat-fix
This commit is contained in:
parent
218bbd54da
commit
b5deb8889a
|
@ -25,14 +25,14 @@ from services.search import search_text
|
||||||
from services.viewed import ViewedStorage
|
from services.viewed import ViewedStorage
|
||||||
|
|
||||||
|
|
||||||
def query_shouts():
|
def query_shouts(slug=None):
|
||||||
"""
|
"""
|
||||||
Базовый запрос для получения публикаций с подзапросами статистики, авторов и тем,
|
Базовый запрос для получения публикаций с подзапросами статистики, авторов и тем,
|
||||||
с агрегацией в строку.
|
с агрегацией в строку.
|
||||||
|
|
||||||
|
:param slug: Опциональный параметр для фильтрации по slug.
|
||||||
:return: Запрос для получения публикаций, aliased_reaction:
|
:return: Запрос для получения публикаций, aliased_reaction:
|
||||||
"""
|
"""
|
||||||
# Создаем алиасы для таблиц для избежания конфликтов имен
|
|
||||||
aliased_reaction = aliased(Reaction)
|
aliased_reaction = aliased(Reaction)
|
||||||
|
|
||||||
# Подзапрос для уникальных авторов, объединенных в строку
|
# Подзапрос для уникальных авторов, объединенных в строку
|
||||||
|
@ -46,6 +46,7 @@ def query_shouts():
|
||||||
func.concat("name:", Author.name),
|
func.concat("name:", Author.name),
|
||||||
func.concat("slug:", Author.slug),
|
func.concat("slug:", Author.slug),
|
||||||
func.concat("pic:", Author.pic),
|
func.concat("pic:", Author.pic),
|
||||||
|
func.concat("caption:", ShoutAuthor.caption), # Добавлено поле caption
|
||||||
),
|
),
|
||||||
" | ",
|
" | ",
|
||||||
).label("authors"), # Используем символ | как разделитель
|
).label("authors"), # Используем символ | как разделитель
|
||||||
|
@ -55,7 +56,7 @@ def query_shouts():
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Подзапрос для уникальных тем, объединенных в строку (без поля body)
|
# Подзапрос для уникальных тем, объединенных в строку (включая main_topic_slug)
|
||||||
topics_subquery = (
|
topics_subquery = (
|
||||||
select(
|
select(
|
||||||
ShoutTopic.shout.label("shout_id"),
|
ShoutTopic.shout.label("shout_id"),
|
||||||
|
@ -69,6 +70,7 @@ def query_shouts():
|
||||||
),
|
),
|
||||||
" | ",
|
" | ",
|
||||||
).label("topics"), # Используем символ | как разделитель
|
).label("topics"), # Используем символ | как разделитель
|
||||||
|
func.max(case((ShoutTopic.main.is_(True), Topic.slug))).label("main_topic_slug") # Получение основного топика
|
||||||
)
|
)
|
||||||
.join(Topic, ShoutTopic.topic == Topic.id)
|
.join(Topic, ShoutTopic.topic == Topic.id)
|
||||||
.group_by(ShoutTopic.shout)
|
.group_by(ShoutTopic.shout)
|
||||||
|
@ -80,7 +82,7 @@ def query_shouts():
|
||||||
select(
|
select(
|
||||||
Shout,
|
Shout,
|
||||||
func.count(case((aliased_reaction.body.is_not(None), 1))).label("comments_stat"),
|
func.count(case((aliased_reaction.body.is_not(None), 1))).label("comments_stat"),
|
||||||
func.count(distinct(aliased_reaction.created_by)).label("followers_stat"),
|
func.count(distinct(ShoutReactionsFollower.follower)).label("followers_stat"),
|
||||||
func.sum(
|
func.sum(
|
||||||
case(
|
case(
|
||||||
(aliased_reaction.kind == ReactionKind.LIKE.value, 1),
|
(aliased_reaction.kind == ReactionKind.LIKE.value, 1),
|
||||||
|
@ -91,18 +93,24 @@ def query_shouts():
|
||||||
func.max(aliased_reaction.created_at).label("last_reacted_at"),
|
func.max(aliased_reaction.created_at).label("last_reacted_at"),
|
||||||
authors_subquery.c.authors.label("authors"),
|
authors_subquery.c.authors.label("authors"),
|
||||||
topics_subquery.c.topics.label("topics"),
|
topics_subquery.c.topics.label("topics"),
|
||||||
|
topics_subquery.c.main_topic_slug.label("main_topic_slug")
|
||||||
)
|
)
|
||||||
.outerjoin(aliased_reaction, aliased_reaction.shout == Shout.id)
|
.outerjoin(aliased_reaction, aliased_reaction.shout == Shout.id)
|
||||||
.outerjoin(authors_subquery, authors_subquery.c.shout_id == Shout.id)
|
.outerjoin(authors_subquery, authors_subquery.c.shout_id == Shout.id)
|
||||||
.outerjoin(topics_subquery, topics_subquery.c.shout_id == Shout.id)
|
.outerjoin(topics_subquery, topics_subquery.c.shout_id == Shout.id)
|
||||||
|
.outerjoin(ShoutReactionsFollower, ShoutReactionsFollower.shout == Shout.id)
|
||||||
.where(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
|
.where(and_(Shout.published_at.is_not(None), Shout.deleted_at.is_(None)))
|
||||||
.group_by(
|
.group_by(
|
||||||
Shout.id,
|
Shout.id,
|
||||||
authors_subquery.c.authors,
|
authors_subquery.c.authors,
|
||||||
topics_subquery.c.topics,
|
topics_subquery.c.topics,
|
||||||
|
topics_subquery.c.main_topic_slug
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if slug:
|
||||||
|
q = q.where(Shout.slug == slug)
|
||||||
|
|
||||||
return q, aliased_reaction
|
return q, aliased_reaction
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,6 +184,7 @@ def get_shouts_with_stats(q, limit, offset=0, author_id=None):
|
||||||
last_reacted_at,
|
last_reacted_at,
|
||||||
authors,
|
authors,
|
||||||
topics,
|
topics,
|
||||||
|
main_topic_slug
|
||||||
) in results:
|
) in results:
|
||||||
shout.authors = parse_aggregated_string(authors, Author)
|
shout.authors = parse_aggregated_string(authors, Author)
|
||||||
shout.topics = parse_aggregated_string(topics, Topic)
|
shout.topics = parse_aggregated_string(topics, Topic)
|
||||||
|
@ -186,6 +195,7 @@ def get_shouts_with_stats(q, limit, offset=0, author_id=None):
|
||||||
"commented": comments_stat or 0,
|
"commented": comments_stat or 0,
|
||||||
"last_reacted_at": last_reacted_at,
|
"last_reacted_at": last_reacted_at,
|
||||||
}
|
}
|
||||||
|
shout.main_topic = main_topic_slug # Присваиваем основной топик
|
||||||
shouts.append(shout)
|
shouts.append(shout)
|
||||||
|
|
||||||
return shouts
|
return shouts
|
||||||
|
@ -278,9 +288,7 @@ async def get_shout(_, info, slug: str):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
q, aliased_reaction = query_shouts()
|
q, aliased_reaction = query_shouts(slug)
|
||||||
q = q.filter(Shout.slug == slug)
|
|
||||||
|
|
||||||
results = session.execute(q).first()
|
results = session.execute(q).first()
|
||||||
if results:
|
if results:
|
||||||
[
|
[
|
||||||
|
@ -291,6 +299,7 @@ async def get_shout(_, info, slug: str):
|
||||||
last_reaction_at,
|
last_reaction_at,
|
||||||
authors,
|
authors,
|
||||||
topics,
|
topics,
|
||||||
|
main_topic_slug
|
||||||
] = results
|
] = results
|
||||||
|
|
||||||
shout.stat = {
|
shout.stat = {
|
||||||
|
@ -304,35 +313,9 @@ async def get_shout(_, info, slug: str):
|
||||||
# Используем класс модели Topic для преобразования строк в объекты
|
# Используем класс модели Topic для преобразования строк в объекты
|
||||||
shout.topics = parse_aggregated_string(topics, Topic)
|
shout.topics = parse_aggregated_string(topics, Topic)
|
||||||
|
|
||||||
for author_caption in (
|
# Добавляем основной топик, если он существует
|
||||||
session.query(ShoutAuthor)
|
shout.main_topic = main_topic_slug
|
||||||
.join(Shout)
|
|
||||||
.where(
|
|
||||||
and_(
|
|
||||||
Shout.slug == slug,
|
|
||||||
Shout.published_at.is_not(None),
|
|
||||||
Shout.deleted_at.is_(None),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
):
|
|
||||||
for author in shout.authors:
|
|
||||||
if author.id == author_caption.author:
|
|
||||||
author.caption = author_caption.caption
|
|
||||||
main_topic = (
|
|
||||||
session.query(Topic.slug)
|
|
||||||
.join(
|
|
||||||
ShoutTopic,
|
|
||||||
and_(
|
|
||||||
ShoutTopic.topic == Topic.id,
|
|
||||||
ShoutTopic.shout == shout.id,
|
|
||||||
ShoutTopic.main.is_(True),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
|
|
||||||
if main_topic:
|
|
||||||
shout.main_topic = main_topic[0]
|
|
||||||
return shout
|
return shout
|
||||||
except Exception as _exc:
|
except Exception as _exc:
|
||||||
import traceback
|
import traceback
|
||||||
|
|
Loading…
Reference in New Issue
Block a user