Eager load submission listing relationships.

remotes/1693176582716663532/tmp_refs/heads/watchparty
Snakes 2022-11-09 09:16:22 -05:00
parent f1ceb5b079
commit ebb3957f41
Signed by: Snakes
GPG Key ID: E745A82778055C7E
6 changed files with 56 additions and 21 deletions

View File

@ -148,6 +148,10 @@ class User(Base):
referrals = relationship("User")
designed_hats = relationship("HatDef", primaryjoin="User.id==HatDef.author_id", back_populates="author")
owned_hats = relationship("Hat", back_populates="owners")
sub_mods = relationship("Mod", primaryjoin="User.id == Mod.user_id", lazy="raise")
sub_exiles = relationship("Exile", primaryjoin="User.id == Exile.user_id", lazy="raise")
_equipped_hats = None
def __init__(self, **kwargs):
@ -216,9 +220,14 @@ class User(Base):
return len(self.designed_hats)
@property
@lazy
def equipped_hats(self):
return g.db.query(Hat).filter_by(user_id=self.id, equipped=True).all()
if self._equipped_hats is None:
self._equipped_hats = g.db.query(Hat).filter_by(user_id=self.id, equipped=True).all()
return self._equipped_hats
@equipped_hats.setter
def equipped_hats(self, hats):
self._equipped_hats = hats
@property
@lazy
@ -294,11 +303,17 @@ class User(Base):
@lazy
def mods(self, sub):
if self.is_suspended_permanently or self.shadowbanned: return False
return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
try:
return any(map(lambda x: x.sub == sub, self.sub_mods))
except:
return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
@lazy
def exiled_from(self, sub):
return bool(g.db.query(Exile.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
try:
return any(map(lambda x: x.sub == sub, self.sub_exiles))
except:
return bool(g.db.query(Exile.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
@property
@lazy

View File

@ -1,4 +1,5 @@
from typing import Callable, Iterable, List, Optional, Union
from sqlalchemy.orm import joinedload, selectinload
from files.classes import *
from flask import g
@ -140,7 +141,7 @@ def get_post(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Option
return x
def get_posts(pids:Iterable[int], v:Optional[User]=None) -> List[Submission]:
def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False) -> List[Submission]:
if not pids: return []
if v:
@ -169,15 +170,34 @@ def get_posts(pids:Iterable[int], v:Optional[User]=None) -> List[Submission]:
blocked,
blocked.c.user_id == Submission.author_id,
isouter=True
).all()
output = [p[0] for p in query]
for i in range(len(output)):
output[i].voted = query[i][1] or 0
output[i].is_blocking = query[i][2] or 0
output[i].is_blocked = query[i][3] or 0
)
else:
output = g.db.query(Submission,).filter(Submission.id.in_(pids)).all()
query = g.db.query(Submission).filter(Submission.id.in_(pids))
if eager:
query = query.options(
selectinload(Submission.author).options(
selectinload(User.owned_hats.and_(Hat.equipped == True)) \
.joinedload(Hat.hat_def, innerjoin=True),
selectinload(User.sub_mods),
selectinload(User.sub_exiles),
),
selectinload(Submission.flags),
selectinload(Submission.awards),
selectinload(Submission.options),
)
results = query.all()
if v:
output = [p[0] for p in results]
for i in range(len(output)):
output[i].voted = results[i][1] or 0
output[i].is_blocking = results[i][2] or 0
output[i].is_blocked = results[i][3] or 0
output[i].author.equipped_hats = output[i].author.owned_hats
else:
output = results
return sorted(output, key=lambda x: pids.index(x.id))

View File

@ -83,7 +83,7 @@ def front_all(v, sub=None, subdomain=None):
holes=holes
)
posts = get_posts(ids, v=v)
posts = get_posts(ids, v=v, eager=True)
if v:
if v.hidevotedon: posts = [x for x in posts if not hasattr(x, 'voted') or not x.voted]

View File

@ -151,7 +151,7 @@ def notifications_posts(v):
next_exists = (len(listing) > 25)
listing = listing[:25]
listing = get_posts(listing, v=v)
listing = get_posts(listing, v=v, eager=True)
for p in listing:
p.unread = p.created_utc > v.last_viewed_post_notifs

View File

@ -163,7 +163,7 @@ def searchposts(v):
next_exists = (len(ids) > PAGE_SIZE)
ids = ids[:PAGE_SIZE]
posts = get_posts(ids, v=v)
posts = get_posts(ids, v=v, eager=True)
if v.client: return {"total":total, "data":[x.json for x in posts]}

View File

@ -44,7 +44,7 @@ def upvoters_downvoters(v, username, uid, cls, vote_cls, vote_dir, template, sta
listing = listing[:PAGE_SIZE]
if cls == Submission:
listing = get_posts(listing, v=v)
listing = get_posts(listing, v=v, eager=True)
elif cls == Comment:
listing = get_comments(listing, v=v)
else:
@ -95,7 +95,7 @@ def upvoting_downvoting(v, username, uid, cls, vote_cls, vote_dir, template, sta
listing = listing[:PAGE_SIZE]
if cls == Submission:
listing = get_posts(listing, v=v)
listing = get_posts(listing, v=v, eager=True)
elif cls == Comment:
listing = get_comments(listing, v=v)
else:
@ -147,7 +147,7 @@ def user_voted(v, username, cls, vote_cls, vote_dir, template, standalone):
next_exists = len(listing) > PAGE_SIZE
listing = listing[:PAGE_SIZE]
if cls == Submission:
listing = get_posts(listing, v=v)
listing = get_posts(listing, v=v, eager=True)
elif cls == Comment:
listing = get_comments(listing, v=v)
else:
@ -713,7 +713,7 @@ def u_username(username, v=None):
for p in sticky:
ids = [p.id] + ids
listing = get_posts(ids, v=v)
listing = get_posts(ids, v=v, eager=True)
if u.unban_utc:
if (v and v.client) or request.path.endswith(".json"):
@ -947,7 +947,7 @@ def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone
next_exists = len(ids) > PAGE_SIZE
ids = ids[:PAGE_SIZE]
if cls is Submission:
listing = get_posts(ids, v=v)
listing = get_posts(ids, v=v, eager=True)
elif cls is Comment:
listing = get_comments(ids, v=v)
else: