From ed78fc9ed5448685413597e3871f30e69e9bc751 Mon Sep 17 00:00:00 2001 From: David Read Date: Tue, 24 Sep 2013 15:18:29 +0100 Subject: [PATCH] [#1038] Improve performance of viewing hierarchy, avoiding groups as SQLAlchemy objects. --- ckan/model/group.py | 20 +++++++++++--------- ckan/tests/models/test_group.py | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ckan/model/group.py b/ckan/model/group.py index 2c69c11a539..6bf544bd635 100644 --- a/ckan/model/group.py +++ b/ckan/model/group.py @@ -197,15 +197,16 @@ def get_children_group_hierarchy(self, type='group'): hierarchy. The ordering is such that children always come after their parent. - :rtype: a list of tuples, each one a Group and the ID of its parent - group. + :rtype: a list of tuples, each one a Group ID, name and title and then + the ID of its parent group. - e.g. >>> dept-health.get_children_group_hierarchy() - [(, u'8a163ba7-5146-4325-90c8-fe53b25e28d0'), - (, u'06e6dbf5-d801-40a1-9dc0-6785340b2ab4'), - (, u'd2e25b41-720c-4ba7-bc8f-bb34b185b3dd')] + e.g. + >>> dept-health.get_children_group_hierarchy() + [(u'8ac0...', u'national-health-service', u'National Health Service', u'e041...'), + (u'b468...', u'nhs-wirral-ccg', u'NHS Wirral CCG', u'8ac0...')] ''' - results = meta.Session.query(Group, 'parent_id').\ + results = meta.Session.query(Group.id, Group.name, Group.title, + 'parent_id').\ from_statement(HIERARCHY_DOWNWARDS_CTE).\ params(id=self.id, type=type).all() return results @@ -242,7 +243,8 @@ def groups_allowed_to_be_its_parent(self, type='group'): ''' all_groups = self.all(group_type=type) - excluded_groups = set(group.name for group, id_ in + excluded_groups = set(group_name + for group_id, group_name, group_title, parent in self.get_children_group_hierarchy(type=type)) excluded_groups.add(self.name) return [group for group in all_groups @@ -398,7 +400,7 @@ def __repr__(self): WHERE m.table_id = c.group_id AND m.table_name = 'group' AND m.state = 'active' ) -SELECT G.*, child.depth, child.table_id as parent_id FROM child +SELECT G.id, G.name, G.title, child.depth, child.table_id as parent_id FROM child INNER JOIN public.group G ON G.id = child.group_id WHERE G.type = :type AND G.state='active' ORDER BY child.depth ASC;""" diff --git a/ckan/tests/models/test_group.py b/ckan/tests/models/test_group.py index 8e12a0fe9b2..71567481953 100644 --- a/ckan/tests/models/test_group.py +++ b/ckan/tests/models/test_group.py @@ -93,7 +93,7 @@ def _search_results(self, query, is_org=False): return set([group.name for group in results]) name_set_from_dicts = lambda groups: set([group['name'] for group in groups]) -name_set_from_group_tuple = lambda tuples: set([t[0].name for t in tuples]) +name_set_from_group_tuple = lambda tuples: set([t[1] for t in tuples]) name_set_from_groups = lambda groups: set([group.name for group in groups]) names_from_groups = lambda groups: [group.name for group in groups] @@ -122,8 +122,8 @@ def test_get_children_group_hierarchy__from_top_2(self): # the first group must be NHS or Food Standards Agency - i.e. on the # first level down nhs = groups[0] - assert_in(nhs[0].name, ('national-health-service', 'food-standards-agency')) - assert_equal(model.Group.get(nhs[1]).name, 'department-of-health') + assert_in(nhs[1], ('national-health-service', 'food-standards-agency')) + assert_equal(model.Group.get(nhs[3]).name, 'department-of-health') def test_get_children_group_hierarchy__from_top(self): assert_equal(name_set_from_group_tuple(model.Group.by_name(u'department-of-health').\