Skip to content

Commit af2131b

Browse files
committed
refactor(users): optimize query
1 parent 68bc018 commit af2131b

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

app/node/user.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from PasarGuardNodeBridge import create_proxy, create_user
2-
from sqlalchemy import select
3-
from sqlalchemy.orm import load_only, selectinload
2+
from sqlalchemy import and_, func, select
43

54
from app.db import AsyncSession
6-
from app.db.models import Group, ProxyInbound, User, UserStatus
5+
from app.db.models import Group, ProxyInbound, User, UserStatus, inbounds_groups_association, users_groups_association
76

87

98
def serialize_user_for_node(id: int, username: str, user_settings: dict, inbounds: list[str] = None):
@@ -28,22 +27,33 @@ def serialize_user_for_node(id: int, username: str, user_settings: dict, inbound
2827

2928
async def core_users(db: AsyncSession):
3029
stmt = (
31-
select(User)
32-
.options(
33-
load_only(User.id, User.username, User.proxy_settings),
34-
selectinload(User.groups),
35-
selectinload(User.groups).selectinload(Group.inbounds).load_only(ProxyInbound.tag),
30+
select(
31+
User.id,
32+
User.username,
33+
User.proxy_settings,
34+
func.group_concat(ProxyInbound.tag.distinct()).label("inbound_tags"),
3635
)
36+
.outerjoin(users_groups_association, User.id == users_groups_association.c.user_id)
37+
.outerjoin(
38+
Group,
39+
and_(
40+
users_groups_association.c.groups_id == Group.id,
41+
Group.is_disabled.is_(False),
42+
),
43+
)
44+
.outerjoin(inbounds_groups_association, Group.id == inbounds_groups_association.c.group_id)
45+
.outerjoin(ProxyInbound, inbounds_groups_association.c.inbound_id == ProxyInbound.id)
3746
.where(User.status.in_([UserStatus.active, UserStatus.on_hold]))
47+
.group_by(User.id, User.username, User.proxy_settings)
3848
)
39-
users = (await db.execute(stmt)).unique().scalars().all()
40-
bridge_users: list = []
4149

42-
for user in users:
43-
inbounds_list = await user.inbounds()
44-
if len(inbounds_list) > 0:
45-
bridge_users.append(serialize_user_for_node(user.id, user.username, user.proxy_settings, inbounds_list))
50+
results = (await db.execute(stmt)).all()
51+
bridge_users: list = []
4652

53+
for row in results:
54+
inbound_tags = row.inbound_tags.split(",") if row.inbound_tags else []
55+
if inbound_tags:
56+
bridge_users.append(serialize_user_for_node(row.id, row.username, row.proxy_settings, inbound_tags))
4757
return bridge_users
4858

4959

0 commit comments

Comments
 (0)