Files
notifications-api/app/dao/services_dao.py
Leo Hemsted 566ae798df 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)
2016-07-15 12:04:38 +01:00

138 lines
3.9 KiB
Python

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,
version_class
)
from app.models import (
NotificationStatistics,
TemplateStatistics,
ProviderStatistics,
VerifyCode,
ApiKey,
Template,
Job,
NotificationHistory,
Notification,
Permission,
User,
InvitedUser,
Service
)
def dao_fetch_all_services():
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
).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)
).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),
Service.id == service_id
).options(
joinedload('users')
).one()
@transactional
@version_class(Service)
def dao_create_service(service, user):
from app.dao.permissions_dao import permission_dao
service.users.append(user)
permission_dao.add_default_service_permissions_for_user(user, service)
service.id = uuid.uuid4() # must be set now so version history model can use same id
service.research_mode = False
db.session.add(service)
@transactional
@version_class(Service)
def dao_update_service(service):
db.session.add(service)
def dao_add_user_to_service(service, user, permissions=[]):
try:
from app.dao.permissions_dao import permission_dao
service.users.append(user)
permission_dao.set_user_service_permission(user, service, permissions, _commit=False)
db.session.add(service)
except Exception as e:
db.session.rollback()
raise e
else:
db.session.commit()
def dao_remove_user_from_service(service, user):
try:
from app.dao.permissions_dao import permission_dao
permission_dao.remove_user_service_permissions(user, service)
service.users.remove(user)
db.session.add(service)
except Exception as e:
db.session.rollback()
raise e
else:
db.session.commit()
def delete_service_and_all_associated_db_objects(service):
def _delete_commit(query):
query.delete()
db.session.commit()
_delete_commit(NotificationStatistics.query.filter_by(service=service))
_delete_commit(TemplateStatistics.query.filter_by(service=service))
_delete_commit(ProviderStatistics.query.filter_by(service=service))
_delete_commit(InvitedUser.query.filter_by(service=service))
_delete_commit(Permission.query.filter_by(service=service))
_delete_commit(ApiKey.query.filter_by(service=service))
_delete_commit(ApiKey.get_history_model().query.filter_by(service_id=service.id))
_delete_commit(NotificationHistory.query.filter_by(service=service))
_delete_commit(Notification.query.filter_by(service=service))
_delete_commit(Job.query.filter_by(service=service))
_delete_commit(Template.query.filter_by(service=service))
_delete_commit(Template.get_history_model().query.filter_by(service_id=service.id))
verify_codes = VerifyCode.query.join(User).filter(User.id.in_([x.id for x in service.users]))
list(map(db.session.delete, verify_codes))
db.session.commit()
users = [x for x in service.users]
map(service.users.remove, users)
[service.users.remove(x) for x in users]
_delete_commit(Service.get_history_model().query.filter_by(id=service.id))
db.session.delete(service)
db.session.commit()
list(map(db.session.delete, users))
db.session.commit()