From 53b80b931f707154d214cad284ee5c7f2a24e0a6 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Mon, 30 Mar 2020 17:47:15 +0100 Subject: [PATCH] fix the sql "if you want something done right, then do it yourself" The ORM was building a weird and inefficient query to get all the users for a given organisation_id: old query: ```sql SELECT users.* FROM users WHERE ( EXISTS ( SELECT 1 FROM user_to_organisation, organisation WHERE users.id = user_to_organisation.user_id AND organisation.id = user_to_organisation.organisation_id AND organisation.id = '63b9557c-22ea-42ac-bcba-edaa50e3ae51' ) ) AND users.state = 'active' ORDER BY users.created_at ``` Note the cross join on users_to_org and org, there are a lot of users in organisations on preview, as one is added every functional test run. Even though they're all filtered out and the query returns the correct data, it still does the nested loop under the hood. new query: ```sql SELECT users.* FROM users JOIN user_to_organisation AS user_to_organisation_1 ON users.id = user_to_organisation_1.user_id JOIN organisation ON organisation.id = user_to_organisation_1.organisation_id WHERE organisation.id = '63b9557c-22ea-42ac-bcba-edaa50e3ae51' AND users.state = 'active' ORDER BY users.created_at; ``` Much more straightforward. --- app/dao/organisation_dao.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/dao/organisation_dao.py b/app/dao/organisation_dao.py index a71ae3603..0dc952eb6 100644 --- a/app/dao/organisation_dao.py +++ b/app/dao/organisation_dao.py @@ -127,8 +127,12 @@ def dao_get_invited_organisation_user(user_id): def dao_get_users_for_organisation(organisation_id): - return User.query.filter( - User.organisations.any(id=organisation_id), + return db.session.query( + User + ).join( + User.organisations + ).filter( + Organisation.id == organisation_id, User.state == 'active' ).order_by(User.created_at).all()