From 4d418b7f959a77be5ab423f5cad0e962a024bef5 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Fri, 20 Mar 2020 16:42:43 +0000 Subject: [PATCH] set delete(synchronize_session=False) on bulk deletes When we're bulk updating, make sure we call `synchronize_session=False`, and make sure that we then commit before we try and access any ORM objects in the session that might be deleted. Tutorial time: when you delete, sqlalchemy needs to work out what to do with objects in the session. "evaluate", "fetch", or False (do nothing). It wants to remove items from the session if you're about to delete them, so that you don't get confused about the state of objects * evaluate compares the delete query to each item in the session in turn. this is the default. if you have lots in the session this could be super slow I guess but that's rarely the case for us. This can lead to errors if the column names are different to the model names, like on our notification and history models. * fetch runs the delete query as if it's a select, and then checks the results of that vs the session. This could be slow. * False doesn't do anything. This means the session will be stale and potentially will contain now-deleted items, until we call `commit` or `expire_all` on the session. https://docs.sqlalchemy.org/en/13/orm/query.html?highlight=query.update#sqlalchemy.orm.query.Query.delete --- app/dao/inbound_sms_dao.py | 2 +- app/dao/notifications_dao.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/dao/inbound_sms_dao.py b/app/dao/inbound_sms_dao.py index ba17ddd26..aea4af653 100644 --- a/app/dao/inbound_sms_dao.py +++ b/app/dao/inbound_sms_dao.py @@ -102,7 +102,7 @@ def _delete_inbound_sms(datetime_to_delete_from, query_filter): while number_deleted > 0: _insert_inbound_sms_history(subquery, query_limit=query_limit) - number_deleted = InboundSms.query.filter(InboundSms.id.in_(subquery)).delete(synchronize_session='fetch') + number_deleted = InboundSms.query.filter(InboundSms.id.in_(subquery)).delete(synchronize_session=False) deleted += number_deleted return deleted diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 3b313a0df..fa046145d 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -377,7 +377,7 @@ def _delete_notifications(notification_type, date_to_delete_from, service_id): Notification.notification_type == notification_type, Notification.service_id == service_id, Notification.created_at < date_to_delete_from, - ).delete() + ).delete(synchronize_session=False) db.session.commit() return deleted