From 3b748ac4c67945b781bd37ef83d61d85b90373fc Mon Sep 17 00:00:00 2001 From: "David J. Kalbfleisch" <1.21e9W@protonmail.com> Date: Tue, 20 Feb 2024 18:30:09 -0500 Subject: [PATCH] #1648 Update all remaining legacy SQL queries to use the new syntax --- .talismanrc | 4 +--- app/dao/complaint_dao.py | 13 +++++-------- app/dao/fido2_key_dao.py | 36 ++++++++++++++++++++++-------------- app/dao/notifications_dao.py | 9 +++++---- app/dao/organisation_dao.py | 18 ++++++++++-------- app/dao/services_dao.py | 26 +++++++++++++------------- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/.talismanrc b/.talismanrc index c587016c70..2744b5b8f2 100644 --- a/.talismanrc +++ b/.talismanrc @@ -13,8 +13,6 @@ fileignoreconfig: checksum: 9a97adf107dbbf0d821a5d210f19b55a27c8b22d0593be3224a10770cd78d4e1 - filename: tests/app/service/test_rest.py checksum: c4331cbc7d3c935ceca4fa94c40034348f00369e50540b02a36dbf6d98bc4fe9 -- filename: tests/app/dao/test_fido2_keys_dao.py - checksum: 35cba2fd6e81a4d9e55fa9ebe8fa6ad8fc1e597aede8495e386f8b7999b6f482 - filename: tests/app/dao/notification_dao/test_notification_dao.py checksum: b32000cfe4245fb5080d1744789913d53b73d68fb0573b6c2e6eaf424ae8255d - filename: tests/app/delivery/test_send_to_providers.py @@ -30,7 +28,7 @@ fileignoreconfig: - filename: tests/app/dao/test_fact_notification_status_dao.py checksum: 2cad8d3b4a53bad53c3adeb9c81968d11b21e75d729976120bdd66ca91031738 - filename: tests/app/dao/test_fido2_keys_dao.py - checksum: 35cba2fd6e81a4d9e55fa9ebe8fa6ad8fc1e597aede8495e386f8b7999b6f482 + checksum: 590f239cf9cfec2028e46f039f079b90517c69be312620257f876cf375d31383 - filename: tests/app/dao/test_api_key_dao.py checksum: 2a5c8291ae13fffac0f6820880d0891248f7b958ef4106a23bd8d0bf3d17e15b - filename: tests/app/v2/notifications/test_push_broadcast_notifications.py diff --git a/app/dao/complaint_dao.py b/app/dao/complaint_dao.py index 4fa90a8e8d..b18a95a353 100644 --- a/app/dao/complaint_dao.py +++ b/app/dao/complaint_dao.py @@ -1,12 +1,10 @@ -from datetime import timedelta - -from flask import current_app -from sqlalchemy import desc, func, select - from app import db from app.dao.dao_utils import transactional from app.models import Complaint from app.utils import get_local_timezone_midnight_in_utc +from datetime import timedelta +from flask import current_app +from sqlalchemy import desc, func, select @transactional @@ -15,9 +13,8 @@ def save_complaint(complaint): def fetch_paginated_complaints(page=1): - return Complaint.query.order_by(desc(Complaint.created_at)).paginate( - page=page, per_page=current_app.config['PAGE_SIZE'] - ) + stmt = select(Complaint).order_by(desc(Complaint.created_at)) + return db.paginate(stmt, page=page, per_page=current_app.config['PAGE_SIZE']) def fetch_complaint_by_id(complaint_id): diff --git a/app/dao/fido2_key_dao.py b/app/dao/fido2_key_dao.py index 18a5bc494c..74efda4267 100644 --- a/app/dao/fido2_key_dao.py +++ b/app/dao/fido2_key_dao.py @@ -1,34 +1,40 @@ +import base64 +import json +import pickle # nosec from app import db -from app.models import Fido2Key, Fido2Session from app.config import Config - from app.dao.dao_utils import transactional - -from sqlalchemy import and_ - +from app.models import Fido2Key, Fido2Session from fido2.webauthn import AttestationObject, CollectedClientData -import json -import pickle # nosec -import base64 +from sqlalchemy import asc, delete, select def delete_fido2_key( user_id, - id, + fido_key_id, ): - db.session.query(Fido2Key).filter(and_(Fido2Key.user_id == user_id, Fido2Key.id == id)).delete() + stmt = delete(Fido2Key).where( + Fido2Key.user_id == user_id, + Fido2Key.id == fido_key_id + ) + db.session.execute(stmt) db.session.commit() def get_fido2_key( user_id, - id, + fido_key_id, ): - return Fido2Key.query.filter(and_(Fido2Key.user_id == user_id, Fido2Key.id == id)).one() + stmt = select(Fido2Key).where( + Fido2Key.user_id == user_id, + Fido2Key.id == fido_key_id + ) + return db.session.scalars(stmt).one() def list_fido2_keys(user_id): - return Fido2Key.query.filter(Fido2Key.user_id == user_id).order_by(Fido2Key.created_at.asc()).all() + stmt = select(Fido2Key).where(Fido2Key.user_id == user_id).order_by(asc(Fido2Key.created_at)) + return db.session.scalars(stmt).all() @transactional @@ -46,7 +52,9 @@ def create_fido2_session( def delete_fido2_session(user_id): - db.session.query(Fido2Session).filter(Fido2Session.user_id == user_id).delete() + stmt = delete(Fido2Session).where(Fido2Session.user_id == user_id) + db.session.execute(stmt) + db.session.commit() def get_fido2_session(user_id): diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index e377433826..07f907b290 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -677,16 +677,17 @@ def _delete_letters_from_s3( if isinstance(service_id, Row): service_id = str(service_id[0]) - letters_to_delete_from_s3 = ( - db.session.query(Notification) - .filter( + stmt = ( + select(Notification) + .where( Notification.notification_type == notification_type, Notification.created_at < date_to_delete_from, Notification.service_id == service_id, ) .limit(query_limit) - .all() ) + letters_to_delete_from_s3 = db.session.scalars(stmt).all() + for letter in letters_to_delete_from_s3: bucket_name = current_app.config['LETTERS_PDF_BUCKET_NAME'] if letter.sent_at: diff --git a/app/dao/organisation_dao.py b/app/dao/organisation_dao.py index 1cf689340d..7953ae1856 100644 --- a/app/dao/organisation_dao.py +++ b/app/dao/organisation_dao.py @@ -1,8 +1,6 @@ -from sqlalchemy import asc, delete, desc, join, select, update -from sqlalchemy.sql.expression import func - from app import db from app.dao.dao_utils import transactional, version_class +from app.model import User from app.models import ( Organisation, Domain, @@ -10,7 +8,7 @@ Service, user_to_organisation, ) -from app.model import User +from sqlalchemy import asc, delete, desc, func, join, select, update def dao_get_organisations(): @@ -24,20 +22,24 @@ def dao_count_organsations_with_live_services(): def dao_get_organisation_services(organisation_id): - return db.session.scalars(select(Organisation).where(Organisation.id == organisation_id)).one().services + stmt = select(Organisation).where(Organisation.id == organisation_id) + return db.session.scalars(stmt).one().services def dao_get_organisation_by_id(organisation_id): - return db.session.scalars(select(Organisation).where(Organisation.id == organisation_id)).one() + stmt = select(Organisation).where(Organisation.id == organisation_id) + return db.session.scalars(stmt).one() def dao_get_organisation_by_email_address(email_address): # Endpoint is unused, query to be removed when endpoint is removed email_address = email_address.lower().replace('.gsi.gov.uk', '.gov.uk') - for domain in Domain.query.order_by(func.char_length(Domain.domain).desc()).all(): + stmt = select(Domain).order_by(desc(func.char_length(Domain.domain))) + for domain in db.session.scalars(stmt).all(): if email_address.endswith('@{}'.format(domain.domain)) or email_address.endswith('.{}'.format(domain.domain)): - return Organisation.query.filter_by(id=domain.organisation_id).one() + stmt = select(Organisation).where(Organisation.id == domain.organisation_id) + return db.session.scalars(stmt).one() return None diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 69760b7264..b12ca7a531 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -1,16 +1,5 @@ import uuid -from datetime import date, datetime, timedelta from app.service.service_data import ServiceData, ServiceDataException - -from cachetools import cached, TTLCache -from notifications_utils.statsd_decorators import statsd -from notifications_utils.timezones import convert_utc_to_local_timezone -from sqlalchemy.sql.expression import asc, case, and_, func -from sqlalchemy.orm import joinedload -from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound -from sqlalchemy import select, delete -from flask import current_app - from app import db from app.dao.dao_utils import ( get_reader_session, @@ -22,6 +11,7 @@ from app.dao.service_sms_sender_dao import insert_service_sms_sender from app.dao.service_user_dao import dao_get_service_user from app.dao.template_folder_dao import dao_get_valid_template_folders_by_id +from app.model import User from app.models import ( AnnualBilling, ApiKey, @@ -45,8 +35,17 @@ KEY_TYPE_TEST, SMS_TYPE, ) -from app.model import User from app.utils import escape_special_characters, get_local_timezone_midnight_in_utc, midnight_n_days_ago +from cachetools import cached, TTLCache +from datetime import date, datetime, timedelta +from flask import current_app +from notifications_utils.statsd_decorators import statsd +from notifications_utils.timezones import convert_utc_to_local_timezone +from sqlalchemy import func, select, delete +from sqlalchemy.orm import joinedload +from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound +from sqlalchemy.sql.expression import asc, case, and_ + # Do not confuse this with "default_service_permissions" in app/dao/permissions_dao.py. DEFAULT_SERVICE_PERMISSIONS = [ @@ -526,4 +525,5 @@ def dao_fetch_active_users_for_service(service_id): def dao_services_by_partial_smtp_name(smtp_name): smtp_name = escape_special_characters(smtp_name) - return Service.query.filter(Service.smtp_user.ilike('%{}%'.format(smtp_name))).one() + stmt = select(Service).where(Service.smtp_user.ilike(f'%{smtp_name}%')) + return db.session.scalars(stmt).one()