Preload seen tickets list

Loads the data in one query instead of one per ticket.
This commit is contained in:
Ivan Habunek 2018-12-14 15:24:14 +01:00 committed by Drew DeVault
parent 36c41f9ae7
commit 40f66d5420
4 changed files with 23 additions and 18 deletions

View File

@ -7,17 +7,18 @@ from todosrht import color
from todosrht.access import get_tracker
from todosrht.email import notify
from todosrht.search import apply_search
from todosrht.tickets import get_last_seen_times
from todosrht.types import TicketSubscription
from todosrht.types import Event, EventType, EventNotification
from todosrht.types import Tracker, Ticket, TicketStatus, TicketAccess
from todosrht.types import Label, TicketLabel, TicketSeen, TicketComment
from todosrht.urls import tracker_url, user_url
from todosrht.types import Label, TicketLabel, TicketComment
from todosrht.urls import tracker_url
from srht.config import cfg
from srht.database import db
from srht.flask import paginate_query, loginrequired
from srht.validation import Validation
from datetime import datetime
from sqlalchemy import func, and_
from sqlalchemy import func
tracker = Blueprint("tracker", __name__)
@ -107,9 +108,17 @@ def return_tracker(tracker, access, **kwargs):
tickets = tickets.filter(Ticket.status == TicketStatus.reported)
tickets, pagination = paginate_query(tickets, results_per_page=25)
# Preload comment counts per ticket
col = TicketComment.ticket_id
ticket_ids = [t.id for t in tickets]
# Find which tickets were seen by the user since last update
seen_ticket_ids = []
if current_user:
seen_times = get_last_seen_times(current_user, tickets)
seen_ticket_ids = [t.id for t in tickets
if t.id in seen_times and seen_times[t.id] >= t.updated]
# Preload comment counts
col = TicketComment.ticket_id
comment_counts = dict(db.session
.query(col, func.count(col))
.filter(col.in_(ticket_ids))
@ -122,7 +131,8 @@ def return_tracker(tracker, access, **kwargs):
return render_template("tracker.html",
tracker=tracker, another=another, tickets=tickets,
access=access, is_subscribed=is_subscribed, search=search,
comment_counts=comment_counts, **pagination, **kwargs)
comment_counts=comment_counts, seen_ticket_ids=seen_ticket_ids,
**pagination, **kwargs)
@tracker.route("/<owner>/<name>")
def tracker_GET(owner, name):

View File

@ -154,7 +154,7 @@
{{ ticket.submitter }}
</a>
</div>
{% if ticket.new_updates(current_user) %}
{% if ticket.id in seen_ticket_ids %}
<div class="comments">
{{icon("comments-o")}}
{{ comment_counts.get(ticket.id, 0) }}

View File

@ -181,3 +181,9 @@ def unassign(ticket, assignee, assigner):
event.ticket_id = ticket.id
event.assigned_user_id = assignee.id
db.session.add(event)
def get_last_seen_times(user, tickets):
"""Fetches last times the user has seen each of the given tickets."""
return dict(db.session.query(TicketSeen.ticket_id, TicketSeen.last_view)
.filter(TicketSeen.ticket_id.in_([t.id for t in tickets]))
.filter(TicketSeen.user == user))

View File

@ -60,14 +60,3 @@ class Ticket(Base):
assigned_users = sa.orm.relationship("User",
secondary="ticket_assignee",
foreign_keys="[TicketAssignee.ticket_id,TicketAssignee.assignee_id]")
def new_updates(self, user):
if not user:
return None
seen = (TicketSeen.query
.filter(TicketSeen.user_id == user.id,
TicketSeen.ticket_id == self.id)
.one_or_none())
if seen:
return seen.last_view >= self.updated
return None