circular-fix-2
All checks were successful
Deploy on push / deploy (push) Successful in 3m49s

This commit is contained in:
Untone 2024-02-24 20:42:19 +03:00
parent a3244fc74b
commit 5e72a08e0f
2 changed files with 59 additions and 2 deletions

View File

@ -16,7 +16,7 @@ from resolvers.topic import topic_follow, topic_unfollow
from resolvers.stat import get_authors_with_stat, query_follows from resolvers.stat import get_authors_with_stat, query_follows
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.event_listeners import DEFAULT_FOLLOWS
from services.notify import notify_follower from services.notify import notify_follower
from services.schema import mutation, query from services.schema import mutation, query
from services.logger import root_logger as logger from services.logger import root_logger as logger

View File

@ -1,9 +1,11 @@
import asyncio import asyncio
from sqlalchemy import select, event from sqlalchemy import select, event, or_, exists, and_
import json import json
from orm.author import Author, AuthorFollower from orm.author import Author, AuthorFollower
from orm.reaction import Reaction
from orm.shout import ShoutAuthor, Shout
from orm.topic import Topic, TopicFollower from orm.topic import Topic, TopicFollower
from resolvers.stat import get_authors_with_stat, get_topics_with_stat from resolvers.stat import get_authors_with_stat, get_topics_with_stat
from services.rediscache import redis from services.rediscache import redis
@ -22,6 +24,61 @@ async def update_author_cache(author: Author, ttl=25 * 60 * 60):
await redis.execute('SETEX', f'id:{author.user}:author', ttl, payload) await redis.execute('SETEX', f'id:{author.user}:author', ttl, payload)
@event.listens_for(Shout, 'after_insert')
@event.listens_for(Shout, 'after_update')
def after_shouts_update(mapper, connection, shout: Shout):
# Создаем подзапрос для проверки наличия авторов в списке shout.authors
subquery = (
select(1)
.where(or_(
Author.id == int(shout.created_by),
and_(
Shout.id == shout.id,
ShoutAuthor.shout == Shout.id,
ShoutAuthor.author == Author.id
)
))
)
# Основной запрос с использованием объединения и подзапроса exists
authors_query = (
select(Author)
.join(ShoutAuthor, Author.id == int(ShoutAuthor.author))
.where(ShoutAuthor.shout == int(shout.id))
.union(
select(Author)
.where(exists(subquery))
)
)
authors = get_authors_with_stat(authors_query, ratings=True)
for author in authors:
asyncio.create_task(update_author_cache(author))
@event.listens_for(Reaction, 'after_insert')
def after_reaction_insert(mapper, connection, reaction: Reaction):
author_subquery = (
select(Author)
.where(Author.id == int(reaction.created_by))
)
replied_author_subquery = (
select(Author)
.join(Reaction, Author.id == int(Reaction.created_by))
.where(Reaction.id == int(reaction.reply_to))
)
author_query = author_subquery.union(replied_author_subquery)
authors = get_authors_with_stat(author_query, ratings=True)
for author in authors:
asyncio.create_task(update_author_cache(author))
shout = connection.execute(select(Shout).where(Shout.id == int(reaction.shout))).first()
if shout:
after_shouts_update(mapper, connection, shout)
@event.listens_for(Author, 'after_insert') @event.listens_for(Author, 'after_insert')
@event.listens_for(Author, 'after_update') @event.listens_for(Author, 'after_update')
def after_author_update(mapper, connection, author: Author): def after_author_update(mapper, connection, author: Author):