diff --git a/heat/db/sqlalchemy/api.py b/heat/db/sqlalchemy/api.py index 10e7f5d74e..d00933e882 100644 --- a/heat/db/sqlalchemy/api.py +++ b/heat/db/sqlalchemy/api.py @@ -496,15 +496,18 @@ def resource_get_all_active_by_stack(context, stack_id): def resource_get_all_by_root_stack(context, stack_id, filters=None, - eager=True): + stack_id_only=False): query = context.session.query( models.Resource ).filter_by( root_stack_id=stack_id - ).options(orm.joinedload("data")) + ) - if eager: - query = query.options(orm.joinedload("rsrc_prop_data")) + if stack_id_only: + query = query.options(orm.load_only("id", "stack_id")) + else: + query = query.options(orm.joinedload("data")).options( + orm.joinedload("rsrc_prop_data")) query = db_filters.exact_filter(query, models.Resource, filters) results = query.all() diff --git a/heat/engine/service.py b/heat/engine/service.py index 321e419972..595a8b0661 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -1749,12 +1749,12 @@ class EngineService(service.ServiceBase): if nested_depth: root_stack_identifier = st.identifier() - # find all resources associated with a root stack - all_r = resource_objects.Resource.get_all_by_root_stack( - cnxt, st.id, None, eager=False) + # find all stacks with resources associated with a root stack + ResObj = resource_objects.Resource + stack_ids = ResObj.get_all_stack_ids_by_root_stack(cnxt, + st.id) # find stacks to the requested nested_depth - stack_ids = {r.stack_id for r in six.itervalues(all_r)} stack_filters = { 'id': stack_ids, 'nested_depth': list(range(nested_depth + 1)) diff --git a/heat/objects/resource.py b/heat/objects/resource.py index 2e3e6c31fb..ef4992ac50 100644 --- a/heat/objects/resource.py +++ b/heat/objects/resource.py @@ -264,18 +264,24 @@ class Resource( return dict(resources) @classmethod - def get_all_by_root_stack(cls, context, stack_id, filters, cache=False, - eager=True): + def get_all_by_root_stack(cls, context, stack_id, filters, cache=False): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, - filters, - eager=eager) + filters) all = cls._resources_to_dict(context, resources_db) if cache: context.cache(ResourceCache).set_by_stack_id(all) return all + @classmethod + def get_all_stack_ids_by_root_stack(cls, context, stack_id): + resources_db = db_api.resource_get_all_by_root_stack( + context, + stack_id, + stack_id_only=True) + return {db_res.stack_id for db_res in six.itervalues(resources_db)} + @classmethod def purge_deleted(cls, context, stack_id): return db_api.resource_purge_deleted(context, stack_id)