readerfix2

This commit is contained in:
Untone 2024-10-31 14:11:59 +03:00
parent bc4432c057
commit 91e4e751d8

View File

@ -161,22 +161,18 @@ def get_shouts_with_stats(q, limit=20, offset=0, author_id=None):
select( select(
func.json_agg( func.json_agg(
func.json_build_object( func.json_build_object(
"id", "id", Author.id,
Author.id, "name", Author.name,
"name", "slug", Author.slug,
Author.name, "pic", Author.pic,
"slug", "caption", ShoutAuthor.caption
Author.slug,
"pic",
Author.pic,
"caption",
ShoutAuthor.caption,
) )
).label("authors") ).label("authors")
) )
.select_from(ShoutAuthor) .select_from(ShoutAuthor)
.join(Author, ShoutAuthor.author == Author.id) .join(Author, ShoutAuthor.author == Author.id)
.where(ShoutAuthor.shout == Shout.id) .where(ShoutAuthor.shout == Shout.id)
.correlate(Shout) # Явная корреляция с таблицей Shout
.scalar_subquery() .scalar_subquery()
) )
@ -185,41 +181,65 @@ def get_shouts_with_stats(q, limit=20, offset=0, author_id=None):
select( select(
func.json_agg( func.json_agg(
func.json_build_object( func.json_build_object(
"id", Topic.id, "title", Topic.title, "slug", Topic.slug, "is_main", ShoutTopic.main "id", Topic.id,
"title", Topic.title,
"slug", Topic.slug,
"is_main", ShoutTopic.main
) )
).label("topics"), ).label("topics"),
func.max(case((ShoutTopic.main, Topic.slug))).label("main_topic_slug"), func.max(
case(
(ShoutTopic.main, Topic.slug)
)
).label("main_topic_slug")
) )
.select_from(ShoutTopic) .select_from(ShoutTopic)
.join(Topic, ShoutTopic.topic == Topic.id) .join(Topic, ShoutTopic.topic == Topic.id)
.where(ShoutTopic.shout == Shout.id) .where(ShoutTopic.shout == Shout.id)
.group_by(ShoutTopic.shout) .group_by(ShoutTopic.shout)
.correlate(Shout) # Явная корреляция с таблицей Shout
.scalar_subquery() .scalar_subquery()
) )
# Определение скалярного подзапроса для последней реакции # Определение скалярного подзапроса для последней реакции
last_reaction = ( last_reaction = (
select(func.max(Reaction.created_at).label("last_reacted_at")) select(
func.max(Reaction.created_at).label("last_reacted_at")
)
.where(Reaction.shout == Shout.id, Reaction.deleted_at.is_(None)) .where(Reaction.shout == Shout.id, Reaction.deleted_at.is_(None))
.scalar_subquery() .scalar_subquery()
) )
# Основной запрос # Основной запрос
q = ( query = (
select( select(
Shout, Shout,
func.count(func.distinct(Reaction.id)).label("comments_stat"), func.count(Reaction.id.distinct()).label("comments_stat"),
func.sum(case((Reaction.kind == "LIKE", 1), (Reaction.kind == "DISLIKE", -1), else_=0)).label( func.sum(
"rating_stat" case(
), (Reaction.kind == "LIKE", 1),
last_reaction.label("last_reacted_at"), (Reaction.kind == "DISLIKE", -1),
authors_subquery.label("authors"), else_=0
topics_subquery.label("topics"), )
func.coalesce(func.json_extract_path_text(topics_subquery, "main_topic_slug"), "").label("main_topic_slug"), ).label("rating_stat"),
last_reaction,
authors_subquery,
topics_subquery,
func.coalesce(
func.json_extract_path_text(topics_subquery, 'main_topic_slug'),
''
).label("main_topic_slug")
) )
.outerjoin(Reaction, Reaction.shout == Shout.id) .outerjoin(Reaction, Reaction.shout == Shout.id)
.filter(Shout.published_at.isnot(None), Shout.deleted_at.is_(None), Shout.featured_at.isnot(None)) .filter(
.group_by(Shout.id, last_reaction) Shout.published_at.isnot(None),
Shout.deleted_at.is_(None),
Shout.featured_at.isnot(None)
)
.group_by(
Shout.id,
last_reaction
)
.order_by(Shout.published_at.desc().nullslast()) .order_by(Shout.published_at.desc().nullslast())
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
@ -227,25 +247,24 @@ def get_shouts_with_stats(q, limit=20, offset=0, author_id=None):
# Добавление фильтрации по author_id, если необходимо # Добавление фильтрации по author_id, если необходимо
if author_id: if author_id:
q = q.filter(Shout.created_by == author_id) query = query.filter(Shout.created_by == author_id)
# Выполнение запроса и обработка результатов # Выполнение запроса и обработка результатов
results = [] with q.session as session:
with local_session() as session: results = session.execute(query).all()
results = session.execute(q).all()
# Формирование списка публикаций с их данными # Формирование списка публикаций с их данными
shouts = [] shouts = []
for [ for row in results:
shout, shout = row.Shout
comments_stat, comments_stat = row.comments_stat
rating_stat, rating_stat = row.rating_stat
last_reacted_at, last_reacted_at = row.last_reacted_at
authors_json, authors_json = row.authors
topics_json, topics_json = row.topics
main_topic_slug, main_topic_slug = row.main_topic_slug
] in results:
# Преобразование JSON данных в объекты # Преобразование JSON данных в объекты
shout.authors = [Author(**author) for author in authors_json] if authors_json else [] shout.authors = [Author(**author) for author in authors_json] if authors_json else []
shout.topics = [Topic(**topic) for topic in topics_json] if topics_json else [] shout.topics = [Topic(**topic) for topic in topics_json] if topics_json else []
@ -634,7 +653,7 @@ async def reacted_shouts_updates(follower_id: int, limit=50, offset=0) -> List[S
with local_session() as session: with local_session() as session:
author = session.query(Author).filter(Author.id == follower_id).first() author = session.query(Author).filter(Author.id == follower_id).first()
if author: if author:
# Публикации, где подписчик является автором # Публикации, где подписчик <EFBFBD><EFBFBD>вляется автором
q1, aliased_reaction1 = query_shouts() q1, aliased_reaction1 = query_shouts()
q1 = q1.filter(Shout.authors.any(id=follower_id)) q1 = q1.filter(Shout.authors.any(id=follower_id))