diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 405d7a9ee..fe201dd8c 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -7,7 +7,7 @@ from notifications_utils.recipients import ( try_validate_and_format_phone_number, validate_and_format_email_address, ) -from sqlalchemy import asc, desc, func, or_, union +from sqlalchemy import asc, desc, or_, select, union from sqlalchemy.orm import joinedload from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.sql import functions @@ -221,7 +221,7 @@ def get_notification_with_personalisation(service_id, notification_id, key_type) return ( Notification.query.filter_by(**filter_dict) - .options(joinedload("template")) + .options(joinedload(Notification.template)) .one() ) @@ -286,7 +286,7 @@ def get_notifications_for_service( query = Notification.query.filter(*filters) query = _filter_query(query, filter_dict) if personalisation: - query = query.options(joinedload("template")) + query = query.options(joinedload(Notification.template)) return query.order_by(desc(Notification.created_at)).paginate( page=page, @@ -572,23 +572,20 @@ def dao_get_notifications_processing_time_stats(start_date, end_date): under_10_secs = Notification.sent_at - Notification.created_at <= timedelta( seconds=10 ) - sum_column = functions.coalesce( - functions.sum(case([(under_10_secs, 1)], else_=0)), 0 + sum_column = functions.coalesce(functions.sum(case((under_10_secs, 1), else_=0)), 0) + + stmt = select( + functions.count(Notification.id).label("messages_total"), + sum_column.label("messages_within_10_secs"), + ).where( + Notification.created_at >= start_date, + Notification.created_at < end_date, + Notification.api_key_id.isnot(None), + Notification.key_type != KeyType.TEST, ) - return ( - db.session.query( - func.count(Notification.id).label("messages_total"), - sum_column.label("messages_within_10_secs"), - ) - .filter( - Notification.created_at >= start_date, - Notification.created_at < end_date, - Notification.api_key_id.isnot(None), - Notification.key_type != KeyType.TEST, - ) - .one() - ) + result = db.session.execute(stmt) + return result.scalar_one() def dao_get_last_notification_added_for_job_id(job_id): diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index f81bd65d5..690317ef4 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -2,7 +2,7 @@ import uuid from datetime import datetime, timedelta from flask import current_app -from sqlalchemy import Float, cast +from sqlalchemy import Float, cast, select from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import and_, asc, case, func @@ -48,7 +48,9 @@ from app.utils import ( def dao_fetch_all_services(only_active=False): - query = Service.query.order_by(asc(Service.created_at)).options(joinedload("users")) + query = Service.query.order_by(asc(Service.created_at)).options( + joinedload(Service.users) + ) if only_active: query = query.filter(Service.active) @@ -174,12 +176,17 @@ def dao_fetch_live_services_data(): def dao_fetch_service_by_id(service_id, only_active=False): - query = Service.query.filter_by(id=service_id).options(joinedload("users")) + stmt = ( + select(Service) + .options(joinedload(Service.users)) + .where(Service.id == service_id) + ) if only_active: - query = query.filter(Service.active) + stmt = stmt.where(Service.active) - return query.one() + result = db.session.execute(stmt) + return result.unique().scalars().first() def dao_fetch_service_by_inbound_number(number): @@ -194,7 +201,7 @@ def dao_fetch_service_by_inbound_number(number): def dao_fetch_service_by_id_with_api_keys(service_id, only_active=False): - query = Service.query.filter_by(id=service_id).options(joinedload("api_keys")) + query = Service.query.filter_by(id=service_id).options(joinedload(Service.api_keys)) if only_active: query = query.filter(Service.active) @@ -234,9 +241,9 @@ def dao_archive_service(service_id): # to ensure that db.session still contains the models when it comes to creating history objects service = ( Service.query.options( - joinedload("templates"), - joinedload("templates.template_redacted"), - joinedload("api_keys"), + joinedload(Service.templates), + joinedload(Service.templates.template_redacted), + joinedload(Service.api_keys), ) .filter(Service.id == service_id) .one() @@ -258,7 +265,7 @@ def dao_archive_service(service_id): 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")) + .options(joinedload(Service.users)) .one() ) @@ -478,7 +485,7 @@ def dao_suspend_service(service_id): # to ensure that db.session still contains the models when it comes to creating history objects service = ( Service.query.options( - joinedload("api_keys"), + joinedload(Service.api_keys), ) .filter(Service.id == service_id) .one()