create get_alias_infos_with_pagination_v3 - reduce nb queries used in get_alias_infos_with_pagination_v2

This commit is contained in:
Son NK 2020-08-21 19:51:48 +02:00
parent 06c48244e4
commit 30fe09185f
4 changed files with 107 additions and 6 deletions

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass
from arrow import Arrow
from sqlalchemy import or_, func, case
from sqlalchemy import or_, func, case, and_
from sqlalchemy.orm import joinedload
from app.config import PAGE_LIMIT
@ -186,6 +186,106 @@ def get_alias_infos_with_pagination_v2(
return ret
def get_alias_infos_with_pagination_v3(
user, page_id=0, query=None, sort=None, alias_filter=None
) -> [AliasInfo]:
ret = []
latest_activity = func.max(
case(
[
(Alias.created_at > EmailLog.created_at, Alias.created_at),
(Alias.created_at < EmailLog.created_at, EmailLog.created_at),
],
else_=Alias.created_at,
)
).label("latest")
sub = (
db.session.query(
Alias.id,
latest_activity,
func.sum(case([(EmailLog.is_reply, 1)], else_=0)).label("nb_reply"),
func.sum(
case(
[(and_(EmailLog.is_reply == False, EmailLog.blocked), 1)], else_=0,
)
).label("nb_blocked"),
func.sum(
case(
[
(
and_(
EmailLog.is_reply == False, EmailLog.blocked == False,
),
1,
)
],
else_=0,
)
).label("nb_forward"),
func.max(EmailLog.created_at).label("max_created_at"),
)
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
.join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
.filter(Alias.user_id == user.id)
.group_by(Alias.id)
.subquery()
)
q = db.session.query(
Alias, Contact, EmailLog, sub.c.nb_reply, sub.c.nb_blocked, sub.c.nb_forward
).filter(
Alias.id == sub.c.id,
Alias.id == Contact.alias_id,
Contact.id == EmailLog.contact_id,
EmailLog.created_at == sub.c.latest,
)
if query:
q = q.filter(
or_(
Alias.email.ilike(f"%{query}%"),
Alias.note.ilike(f"%{query}%"),
Alias.name.ilike(f"%{query}%"),
)
)
if alias_filter == "enabled":
q = q.filter(Alias.enabled)
elif alias_filter == "disabled":
q = q.filter(Alias.enabled == False)
if sort == "old2new":
q = q.order_by(Alias.created_at)
elif sort == "new2old":
q = q.order_by(Alias.created_at.desc())
elif sort == "a2z":
q = q.order_by(Alias.email)
elif sort == "z2a":
q = q.order_by(Alias.email.desc())
else:
# default sorting
q = q.order_by(sub.c.latest.desc())
q = list(q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT))
for alias, contact, email_log, nb_reply, nb_blocked, nb_forward in q:
ret.append(
AliasInfo(
alias=alias,
mailbox=alias.mailbox,
mailboxes=alias.mailboxes,
nb_forward=nb_forward,
nb_blocked=nb_blocked,
nb_reply=nb_reply,
latest_email_log=email_log,
latest_contact=contact,
)
)
return ret
def get_alias_info(alias: Alias) -> AliasInfo:
q = (
db.session.query(Contact, EmailLog)

View File

@ -10,9 +10,9 @@ from app.api.serializer import (
serialize_contact,
get_alias_infos_with_pagination,
get_alias_contacts,
get_alias_infos_with_pagination_v2,
serialize_alias_info_v2,
get_alias_info_v2,
get_alias_infos_with_pagination_v3,
)
from app.config import EMAIL_DOMAIN
from app.dashboard.views.alias_log import get_alias_log
@ -107,7 +107,7 @@ def get_aliases_v2():
if data:
query = data.get("query")
alias_infos: [AliasInfo] = get_alias_infos_with_pagination_v2(
alias_infos: [AliasInfo] = get_alias_infos_with_pagination_v3(
user, page_id=page_id, query=query
)

View File

@ -171,7 +171,7 @@
{% set alias = alias_info.alias %}
<div class="col-12 col-lg-6">
<div class="card p-4 shadow-sm {% if alias_info.alias.id == highlight_alias_id %} highlight-row {% endif %} ">
<div class="card p-4 shadow-sm {% if alias.id == highlight_alias_id %} highlight-row {% endif %} ">
<div class="row">
<div class="col-8">

View File

@ -1,10 +1,11 @@
from dataclasses import dataclass
from flask import render_template, request, redirect, url_for, flash
from flask_login import login_required, current_user
from sqlalchemy.orm import joinedload
from app import alias_utils
from app.api.serializer import get_alias_infos_with_pagination_v2
from app.api.serializer import get_alias_infos_with_pagination_v3
from app.config import PAGE_LIMIT
from app.dashboard.base import dashboard_bp
from app.extensions import db
@ -136,7 +137,7 @@ def index():
stats = get_stats(current_user)
alias_infos = get_alias_infos_with_pagination_v2(
alias_infos = get_alias_infos_with_pagination_v3(
current_user, page, query, sort, alias_filter
)
last_page = len(alias_infos) < PAGE_LIMIT