Coverage for src/couchers/materialized_views.py: 100%
24 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-10-21 08:09 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-10-21 08:09 +0000
1import logging
3from google.protobuf import empty_pb2
4from sqlalchemy import Index
5from sqlalchemy.sql import func
6from sqlalchemy.sql import select as sa_select
7from sqlalchemy_utils import create_materialized_view, refresh_materialized_view
9from couchers.db import session_scope
10from couchers.models import Base, ClusterRole, ClusterSubscription, Upload, User
12logger = logging.getLogger(__name__)
14cluster_subscription_counts_selectable = (
15 sa_select(
16 ClusterSubscription.cluster_id.label("cluster_id"),
17 func.count().label("count"),
18 )
19 .select_from(ClusterSubscription)
20 .outerjoin(User, User.id == ClusterSubscription.user_id)
21 .where(User.is_visible)
22 .group_by(ClusterSubscription.cluster_id)
23)
25cluster_subscription_counts = create_materialized_view(
26 "cluster_subscription_counts",
27 cluster_subscription_counts_selectable,
28 Base.metadata,
29 [
30 Index(
31 "uq_cluster_subscription_counts_cluster_id",
32 cluster_subscription_counts_selectable.c.cluster_id,
33 unique=True,
34 )
35 ],
36)
38cluster_admin_counts_selectable = (
39 sa_select(
40 ClusterSubscription.cluster_id.label("cluster_id"),
41 func.count().label("count"),
42 )
43 .select_from(ClusterSubscription)
44 .outerjoin(User, User.id == ClusterSubscription.user_id)
45 .where(ClusterSubscription.role == ClusterRole.admin)
46 .where(User.is_visible)
47 .group_by(ClusterSubscription.cluster_id)
48)
50cluster_admin_counts = create_materialized_view(
51 "cluster_admin_counts",
52 cluster_admin_counts_selectable,
53 Base.metadata,
54 [Index("uq_cluster_admin_counts_cluster_id", cluster_admin_counts_selectable.c.cluster_id, unique=True)],
55)
57lite_users_selectable = (
58 sa_select(
59 User.id.label("id"),
60 User.username.label("username"),
61 User.name.label("name"),
62 User.city.label("city"),
63 User.age.label("age"),
64 func.ST_Y(User.geom).label("lat"),
65 func.ST_X(User.geom).label("lng"),
66 User.geom_radius.label("radius"),
67 User.is_visible.label("is_visible"),
68 Upload.filename.label("avatar_filename"),
69 )
70 .select_from(User)
71 .outerjoin(Upload, Upload.key == User.avatar_key)
72)
74lite_users = create_materialized_view(
75 "lite_users",
76 lite_users_selectable,
77 Base.metadata,
78 [Index("uq_lite_users_id", lite_users_selectable.c.id, unique=True)],
79)
82def refresh_materialized_views(payload: empty_pb2.Empty):
83 logger.info("Refreshing materialized views")
84 with session_scope() as session:
85 refresh_materialized_view(session, "cluster_subscription_counts", concurrently=True)
86 refresh_materialized_view(session, "cluster_admin_counts", concurrently=True)
89def refresh_materialized_views_rapid(payload: empty_pb2.Empty):
90 logger.info("Refreshing materialized views (rapid)")
91 with session_scope() as session:
92 refresh_materialized_view(session, "lite_users", concurrently=True)