Speed up GET services endpoints

Add additional relationships to exclude in the ServiceSchema metaclass.
Marshmallow by default lazily loads relationships when dumping, so any
relationships we know we won't need, we can exclude and avoid a DB call.
Lots of tables are linked to services, so it loads a lot of tables.
So don't load statistics tables, since they're clearly not needed.

We *do* however want to return the users for the service - they're used
in a few places. If we're returning all services, then we don't want to
make separate queries for these users, so we modify the services_dao
queries to load users the first time round. This should speed up all
GET queries to the services endpoints, most notably pages that get many
services (platform_admin, choose service, login)
This commit is contained in:
Leo Hemsted
2016-07-15 11:34:59 +01:00
parent 327b0dcd02
commit 566ae798df
2 changed files with 33 additions and 5 deletions

View File

@@ -3,6 +3,7 @@ import uuid
from app import db
from app.models import Service
from sqlalchemy import asc
from sqlalchemy.orm import joinedload
from app.dao.dao_utils import (
transactional,
@@ -27,19 +28,38 @@ from app.models import (
def dao_fetch_all_services():
return Service.query.order_by(asc(Service.created_at)).all()
return Service.query.order_by(
asc(Service.created_at)
).options(
joinedload('users')
).all()
def dao_fetch_service_by_id(service_id):
return Service.query.filter_by(id=service_id).one()
return Service.query.filter_by(
id=service_id
).options(
joinedload('users')
).one()
def dao_fetch_all_services_by_user(user_id):
return Service.query.filter(Service.users.any(id=user_id)).order_by(asc(Service.created_at)).all()
return Service.query.filter(
Service.users.any(id=user_id)
).order_by(
asc(Service.created_at)
).options(
joinedload('users')
).all()
def dao_fetch_service_by_id_and_user(service_id, user_id):
return Service.query.filter(Service.users.any(id=user_id)).filter_by(id=service_id).one()
return Service.query.filter(
Service.users.any(id=user_id),
Service.id == service_id
).options(
joinedload('users')
).one()
@transactional

View File

@@ -106,7 +106,15 @@ class ServiceSchema(BaseSchema):
class Meta:
model = models.Service
exclude = ("updated_at", "created_at", "api_keys", "templates", "jobs", 'old_id')
exclude = ('updated_at',
'created_at',
'api_keys',
'templates',
'jobs',
'old_id',
'template_statistics',
'service_provider_stats',
'service_notification_stats')
strict = True
@validates('sms_sender')