From 67fa44b062cf532028e2623897dfba261d0814f6 Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 21 Feb 2024 18:07:02 +0300 Subject: [PATCH] redis-save-fi --- services/db.py | 15 +++++++++++---- services/follows.py | 28 +++++++++------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/services/db.py b/services/db.py index 2b9cdc02..58a8767b 100644 --- a/services/db.py +++ b/services/db.py @@ -22,6 +22,7 @@ T = TypeVar("T") REGISTRY: Dict[str, type] = {} Base = declarative_base() + def profile_sqlalchemy_queries(threshold=0.1): def decorator(fn): @wraps(fn) @@ -30,12 +31,15 @@ def profile_sqlalchemy_queries(threshold=0.1): if elapsed is not None: print(f"Query took {elapsed:.3f} seconds to execute.") stats = stat_loader() - stats.sort_stats('cumulative') + stats.sort_stats("cumulative") stats.print_stats() return result + return wrapper + return decorator + def _profile(fn, threshold, *args, **kw): began = time.time() result = fn(*args, **kw) @@ -46,24 +50,27 @@ def _profile(fn, threshold, *args, **kw): else: return None, None, result + # Перехватчики для журнала запросов SQLAlchemy @event.listens_for(Engine, "before_cursor_execute") def before_cursor_execute(conn, cursor, statement, parameters, context, executemany): conn._query_start_time = time.time() + @event.listens_for(Engine, "after_cursor_execute") def after_cursor_execute(conn, cursor, statement, parameters, context, executemany): - if hasattr(conn, '_query_start_time'): + if hasattr(conn, "_query_start_time"): elapsed = time.time() - conn._query_start_time del conn._query_start_time if elapsed > 0.2: # Adjust threshold as needed - logger.debug(f"{'*' * math.floor(elapsed)} {elapsed:.3f} seconds to execute.") + logger.debug( + f"{'*' * math.floor(elapsed)} {elapsed:.3f} seconds to execute." + ) # Profile the query if execution time exceeds the threshold profiler = profile_sqlalchemy_queries(threshold=0.2)(cursor.execute) profiler(statement, parameters) - def local_session(src=""): return Session(bind=engine, expire_on_commit=False) diff --git a/services/follows.py b/services/follows.py index a8e5b100..6e463974 100644 --- a/services/follows.py +++ b/services/follows.py @@ -14,34 +14,34 @@ from services.viewed import ViewedStorage @event.listens_for(Author, "after_insert") @event.listens_for(Author, "after_update") -def after_author_update(mapper, connection, target): +def after_author_update(mapper, connection, target: Author): redis_key = f"user:{target.user}:author" - asyncio.create_task(redis.execute("set", redis_key, json.dumps(vars(target)))) + asyncio.create_task(redis.execute("set", redis_key, json.dumps(target.dict()))) @event.listens_for(TopicFollower, "after_insert") -def after_topic_follower_insert(mapper, connection, target): +def after_topic_follower_insert(mapper, connection, target: TopicFollower): asyncio.create_task( handle_topic_follower_change(connection, target.topic, target.follower, True) ) @event.listens_for(TopicFollower, "after_delete") -def after_topic_follower_delete(mapper, connection, target): +def after_topic_follower_delete(mapper, connection, target: TopicFollower): asyncio.create_task( handle_topic_follower_change(connection, target.topic, target.follower, False) ) @event.listens_for(AuthorFollower, "after_insert") -def after_author_follower_insert(mapper, connection, target): +def after_author_follower_insert(mapper, connection, target: AuthorFollower): asyncio.create_task( handle_author_follower_change(connection, target.author, target.follower, True) ) @event.listens_for(AuthorFollower, "after_delete") -def after_author_follower_delete(mapper, connection, target): +def after_author_follower_delete(mapper, connection, target: AuthorFollower): asyncio.create_task( handle_author_follower_change(connection, target.author, target.follower, False) ) @@ -61,7 +61,7 @@ async def update_follows_for_user(connection, user_id, entity_type, entity, is_i ], } if is_insert: - follows[f"{entity_type}s"].append(entity) + follows[f"{entity_type}s"].append(entity.dict()) else: # Remove the entity from follows follows[f"{entity_type}s"] = [ @@ -125,21 +125,11 @@ class FollowsCached: redis_key = f"user:{author.user}:author" author_dict = author.dict() if isinstance(author_dict, dict): - filtered_author_dict = { - k: v for k, v in author_dict.items() if v is not None - } - await redis.execute( - "set", redis_key, json.dumps(filtered_author_dict) - ) + await redis.execute("set", redis_key, json.dumps(author_dict)) follows = await get_author_follows(None, None, user=author.user) if isinstance(follows, dict): - filtered_follows = { - k: v for k, v in follows.items() if v is not None - } redis_key = f"user:{author.user}:follows" - await redis.execute( - "set", redis_key, json.dumps(filtered_follows) - ) + await redis.execute("set", redis_key, json.dumps(follows)) @staticmethod async def worker():