diff --git a/tests/services/test_tasks_service.py b/tests/services/test_tasks_service.py index 969cf82c3..cb4b4d2a2 100644 --- a/tests/services/test_tasks_service.py +++ b/tests/services/test_tasks_service.py @@ -256,6 +256,34 @@ def test_get_task_dicts_for_entity_with_relations_attaches_assignees( self.assertEqual(task["assignees"], [person_id]) self.assertTrue(all(isinstance(a, str) for a in task["assignees"])) + def test_get_tasks_for_project_loads_only_assignee_ids(self): + from sqlalchemy import event + from zou.app import db + + person_id = str(self.person.id) + statements = [] + + def collect(conn, cursor, statement, *args, **kwargs): + statements.append(statement) + + engine = db.session.get_bind() + event.listen(engine, "before_cursor_execute", collect) + try: + tasks = tasks_service.get_tasks_for_project(self.project.id) + finally: + event.remove(engine, "before_cursor_execute", collect) + + assignees = [a for task in tasks for a in task["assignees"]] + self.assertIn(person_id, assignees) + self.assertTrue(all(isinstance(a, str) for a in assignees)) + + person_link_statements = [ + s for s in statements if "task_person_link" in s.lower() + ] + self.assertTrue(person_link_statements) + for statement in person_link_statements: + self.assertNotIn("person.password", statement) + def test_get_task_dicts_for_entity_relations_avoids_n_plus_one(self): from sqlalchemy import event from zou.app import db diff --git a/zou/app/services/tasks_service.py b/zou/app/services/tasks_service.py index 224a6f42e..952695aa7 100644 --- a/zou/app/services/tasks_service.py +++ b/zou/app/services/tasks_service.py @@ -17,7 +17,7 @@ from sqlalchemy.exc import StatementError, IntegrityError, DataError from sqlalchemy.sql import func from sqlalchemy.sql.expression import case -from sqlalchemy.orm import aliased, selectinload +from sqlalchemy.orm import aliased, load_only, selectinload from zou.app import config, db from zou.app.utils import events @@ -1890,7 +1890,9 @@ def get_tasks_for_project( Return all tasks for given project. """ query = ( - Task.query.options(selectinload(Task.assignees)) + Task.query.options( + selectinload(Task.assignees).load_only(Person.id) + ) .filter(Task.project_id == project_id) .order_by(Task.updated_at.desc()) )