You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/03/14 23:41:41 UTC

[2/3] incubator-ariatosca git commit: Many cleanups; use dict for many models

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0f040a2b/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 613b371..13f355d 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -51,11 +51,11 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
     :ivar meta_data: Custom annotations
     :vartype meta_data: {basestring: :class:`Metadata`}
     :ivar node: Nodes
-    :vartype node: [:class:`Node`]
+    :vartype node: {basestring: :class:`Node`}
     :ivar groups: Groups of nodes
-    :vartype groups: [:class:`Group`]
+    :vartype groups: {basestring: :class:`Group`}
     :ivar policies: Policies
-    :vartype policies: [:class:`Policy`]
+    :vartype policies: {basestring: :class:`Policy`]}
     :ivar substitution: The entire service can appear as a node
     :vartype substitution: :class:`Substitution`
     :ivar inputs: Externally provided parameters
@@ -88,48 +88,46 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     @declared_attr
     def service_template(cls):
-        return cls._create_many_to_one_relationship('service_template')
+        return cls._declare_many_to_one('service_template')
 
     description = Column(Text)
 
     @declared_attr
     def meta_data(cls):
         # Warning! We cannot use the attr name "metadata" because it's used by SqlAlchemy!
-        return cls._create_many_to_many_relationship('metadata', dict_key='name')
+        return cls._declare_many_to_many('metadata', dict_key='name')
 
     @declared_attr
     def nodes(cls):
-        return cls._create_one_to_many_relationship('node')
+        return cls._declare_one_to_many('node', dict_key='name')
 
     @declared_attr
     def groups(cls):
-        return cls._create_one_to_many_relationship('group')
+        return cls._declare_one_to_many('group', dict_key='name')
 
     @declared_attr
     def policies(cls):
-        return cls._create_one_to_many_relationship('policy')
+        return cls._declare_one_to_many('policy', dict_key='name')
 
     @declared_attr
     def substitution(cls):
-        return cls._create_one_to_one_relationship('substitution')
+        return cls._declare_one_to_one('substitution')
 
     @declared_attr
     def inputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='inputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
 
     @declared_attr
     def outputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='outputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='outputs', dict_key='name')
 
     @declared_attr
     def workflows(cls):
-        return cls._create_one_to_many_relationship('operation', dict_key='name')
+        return cls._declare_one_to_many('operation', dict_key='name')
 
     @declared_attr
     def plugin_specifications(cls):
-        return cls._create_many_to_many_relationship('plugin_specification')
+        return cls._declare_many_to_many('plugin_specification')
 
     created_at = Column(DateTime, nullable=False, index=True)
     updated_at = Column(DateTime)
@@ -143,58 +141,43 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     # region foreign keys
 
-    __private_fields__ = ['substituion_fk',
-                          'service_template_fk']
-
-    # Service one-to-one to Substitution
     @declared_attr
     def substitution_fk(cls):
-        return cls._create_foreign_key('substitution', nullable=True)
+        """Service one-to-one to Substitution"""
+        return cls._declare_fk('substitution', nullable=True)
 
-    # Service many-to-one to ServiceTemplate
     @declared_attr
     def service_template_fk(cls):
-        return cls._create_foreign_key('service_template', nullable=True)
+        """For Service many-to-one to ServiceTemplate"""
+        return cls._declare_fk('service_template', nullable=True)
+
+    # endregion
+
+    # region association proxies
+
+    @declared_attr
+    def service_template_name(cls):
+        """Required for use by SqlAlchemy queries"""
+        return association_proxy('service_template', 'name')
 
     # endregion
 
     def satisfy_requirements(self):
         satisfied = True
-        for node in self.nodes:
+        for node in self.nodes.itervalues():
             if not node.satisfy_requirements():
                 satisfied = False
         return satisfied
 
     def validate_capabilities(self):
         satisfied = True
-        for node in self.nodes:
+        for node in self.nodes.itervalues():
             if not node.validate_capabilities():
                 satisfied = False
         return satisfied
 
-    def find_nodes(self, node_template_name):
-        nodes = []
-        for node in self.nodes:
-            if node.node_template.name == node_template_name:
-                nodes.append(node)
-        return collections.FrozenList(nodes)
-
-    def get_node_ids(self, node_template_name):
-        return collections.FrozenList((node.name for node in self.find_nodes(node_template_name)))
-
-    def find_groups(self, group_template_name):
-        groups = []
-        for group in self.groups:
-            if group.template_name == group_template_name:
-                groups.append(group)
-        return collections.FrozenList(groups)
-
-    def get_group_ids(self, group_template_name):
-        return collections.FrozenList((group.name
-                                       for group in self.find_groups(group_template_name)))
-
     def is_node_a_target(self, target_node):
-        for node in self.nodes:
+        for node in self.nodes.itervalues():
             if self._is_node_a_target(node, target_node):
                 return True
         return False
@@ -226,9 +209,9 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     def validate(self):
         utils.validate_dict_values(self.meta_data)
-        utils.validate_list_values(self.nodes)
-        utils.validate_list_values(self.groups)
-        utils.validate_list_values(self.policies)
+        utils.validate_dict_values(self.nodes)
+        utils.validate_dict_values(self.groups)
+        utils.validate_dict_values(self.policies)
         if self.substitution is not None:
             self.substitution.validate()
         utils.validate_dict_values(self.inputs)
@@ -237,9 +220,9 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     def coerce_values(self, container, report_issues):
         utils.coerce_dict_values(container, self.meta_data, report_issues)
-        utils.coerce_list_values(container, self.nodes, report_issues)
-        utils.coerce_list_values(container, self.groups, report_issues)
-        utils.coerce_list_values(container, self.policies, report_issues)
+        utils.coerce_dict_values(container, self.nodes, report_issues)
+        utils.coerce_dict_values(container, self.groups, report_issues)
+        utils.coerce_dict_values(container, self.policies, report_issues)
         if self.substitution is not None:
             self.substitution.coerce_values(container, report_issues)
         utils.coerce_dict_values(container, self.inputs, report_issues)
@@ -251,11 +234,11 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
         if self.description is not None:
             console.puts(context.style.meta(self.description))
         utils.dump_dict_values(self.meta_data, 'Metadata')
-        for node in self.nodes:
+        for node in self.nodes.itervalues():
             node.dump()
-        for group in self.groups:
+        for group in self.groups.itervalues():
             group.dump()
-        for policy in self.policies:
+        for policy in self.policies.itervalues():
             policy.dump()
         if self.substitution is not None:
             self.substitution.dump()
@@ -264,7 +247,7 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
         utils.dump_dict_values(self.workflows, 'Workflows')
 
     def dump_graph(self):
-        for node in self.nodes:
+        for node in self.nodes.itervalues():
             if not self.is_node_a_target(node):
                 self._dump_graph_node(node)
 
@@ -293,6 +276,10 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
                     with console.indent(3):
                         self._dump_graph_node(target_node)
 
+    __private_fields__ = ['substitution_fk',
+                          'service_template_fk',
+                          'service_template_name']
+
 
 class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
     """
@@ -350,50 +337,47 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     @declared_attr
     def node_template(cls):
-        return cls._create_many_to_one_relationship('node_template')
+        return cls._declare_many_to_one('node_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interfaces(cls):
-        return cls._create_one_to_many_relationship('interface', dict_key='name')
+        return cls._declare_one_to_many('interface', dict_key='name')
 
     @declared_attr
     def artifacts(cls):
-        return cls._create_one_to_many_relationship('artifact', dict_key='name')
+        return cls._declare_one_to_many('artifact', dict_key='name')
 
     @declared_attr
     def capabilities(cls):
-        return cls._create_one_to_many_relationship('capability', dict_key='name')
+        return cls._declare_one_to_many('capability', dict_key='name')
 
     @declared_attr
     def outbound_relationships(cls):
-        return cls._create_one_to_many_relationship('relationship',
-                                                    foreign_key='source_node_fk',
-                                                    backreference='source_node')
+        return cls._declare_one_to_many('relationship', child_fk='source_node_fk',
+                                        child_property='source_node')
 
     @declared_attr
     def inbound_relationships(cls):
-        return cls._create_one_to_many_relationship('relationship',
-                                                    foreign_key='target_node_fk',
-                                                    backreference='target_node')
+        return cls._declare_one_to_many('relationship', child_fk='target_node_fk',
+                                        child_property='target_node')
 
     @declared_attr
     def plugin_specifications(cls):
-        return cls._create_many_to_many_relationship('plugin_specification')
+        return cls._declare_many_to_many('plugin_specification', dict_key='name')
 
     @declared_attr
     def host(cls):
-        return cls._create_relationship_to_self('host_fk')
+        return cls._declare_one_to_one_self('host_fk')
 
     # region orchestration
 
@@ -402,10 +386,6 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
     state = Column(Text, nullable=False)
     version = Column(Integer, default=1)
 
-    @declared_attr
-    def service_name(cls):
-        return association_proxy('service', 'name')
-
     @property
     def ip(self):
         # TODO: totally broken
@@ -424,30 +404,34 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'host_fk',
-                          'service_fk',
-                          'node_template_fk']
-
-    # Node many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Node many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Node one-to-one to Node
     @declared_attr
     def host_fk(cls):
-        return cls._create_foreign_key('node', nullable=True)
+        """For Node one-to-one to Node"""
+        return cls._declare_fk('node', nullable=True)
 
-    # Service one-to-many to Node
     @declared_attr
     def service_fk(cls):
-        return cls._create_foreign_key('service')
+        """For Service one-to-many to Node"""
+        return cls._declare_fk('service')
 
-    # Node many-to-one to NodeTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template', nullable=True)
+        """For Node many-to-one to NodeTemplate"""
+        return cls._declare_fk('node_template', nullable=True)
+
+    # endregion
+
+    # region association proxies
+
+    @declared_attr
+    def service_name(cls):
+        """Required for use by SqlAlchemy queries"""
+        return association_proxy('service', 'name')
 
     # endregion
 
@@ -475,7 +459,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
         from . import models
         context = ConsumptionContext.get_thread_local()
         # Find target nodes
-        target_nodes = context.modeling.instance.find_nodes(target_node_template.name)
+        target_nodes = target_node_template.nodes.all()
         if target_nodes:
             target_node = None
             target_capability = None
@@ -539,7 +523,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
     def as_raw(self):
         return collections.OrderedDict((
             ('name', self.name),
-            ('type_name', self.type_name),
+            ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interfaces', formatting.as_raw_list(self.interfaces)),
             ('artifacts', formatting.as_raw_list(self.artifacts)),
@@ -583,6 +567,12 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods
             utils.dump_dict_values(self.capabilities, 'Capabilities')
             utils.dump_list_values(self.outbound_relationships, 'Relationships')
 
+    __private_fields__ = ['type_fk',
+                          'host_fk',
+                          'service_fk',
+                          'node_template_fk',
+                          'service_name']
+
 
 class GroupBase(InstanceModelMixin):
     """
@@ -613,47 +603,42 @@ class GroupBase(InstanceModelMixin):
 
     @declared_attr
     def group_template(cls):
-        return cls._create_many_to_one_relationship('group_template')
+        return cls._declare_many_to_one('group_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def nodes(cls):
-        return cls._create_many_to_many_relationship('node')
+        return cls._declare_many_to_many('node')
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interfaces(cls):
-        return cls._create_one_to_many_relationship('interface', dict_key='name')
+        return cls._declare_one_to_many('interface', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'service_fk',
-                          'group_template_fk']
-
-    # Group many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Group many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Service one-to-many to Group
     @declared_attr
     def service_fk(cls):
-        return cls._create_foreign_key('service')
+        """For Service one-to-many to Group"""
+        return cls._declare_fk('service')
 
-    # Group many-to-one to GroupTemplate
     @declared_attr
     def group_template_fk(cls):
-        return cls._create_foreign_key('group_template', nullable=True)
+        """For Group many-to-one to GroupTemplate"""
+        return cls._declare_fk('group_template', nullable=True)
 
     # endregion
 
@@ -685,6 +670,10 @@ class GroupBase(InstanceModelMixin):
                     for node in self.nodes:
                         console.puts(context.style.node(node.name))
 
+    __private_fields__ = ['type_fk',
+                          'service_fk',
+                          'group_template_fk']
+
 
 class PolicyBase(InstanceModelMixin):
     """
@@ -713,47 +702,42 @@ class PolicyBase(InstanceModelMixin):
 
     @declared_attr
     def policy_template(cls):
-        return cls._create_many_to_one_relationship('policy_template')
+        return cls._declare_many_to_one('policy_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def nodes(cls):
-        return cls._create_many_to_many_relationship('node')
+        return cls._declare_many_to_many('node')
 
     @declared_attr
     def groups(cls):
-        return cls._create_many_to_many_relationship('group')
+        return cls._declare_many_to_many('group')
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'service_fk',
-                          'policy_template_fk']
-
-    # Policy many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Policy many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Service one-to-many to Policy
     @declared_attr
     def service_fk(cls):
-        return cls._create_foreign_key('service')
+        """For Service one-to-many to Policy"""
+        return cls._declare_fk('service')
 
-    # Policy many-to-one to PolicyTemplate
     @declared_attr
     def policy_template_fk(cls):
-        return cls._create_foreign_key('policy_template', nullable=True)
+        """For Policy many-to-one to PolicyTemplate"""
+        return cls._declare_fk('policy_template', nullable=True)
 
     # endregion
 
@@ -761,7 +745,7 @@ class PolicyBase(InstanceModelMixin):
     def as_raw(self):
         return collections.OrderedDict((
             ('name', self.name),
-            ('type_name', self.type_name),
+            ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
     def validate(self):
@@ -787,6 +771,10 @@ class PolicyBase(InstanceModelMixin):
                     for group in self.groups:
                         console.puts(context.style.node(group.name))
 
+    __private_fields__ = ['type_fk',
+                          'service_fk',
+                          'policy_template_fk']
+
 
 class SubstitutionBase(InstanceModelMixin):
     """
@@ -809,30 +797,27 @@ class SubstitutionBase(InstanceModelMixin):
 
     @declared_attr
     def substitution_template(cls):
-        return cls._create_many_to_one_relationship('substitution_template')
+        return cls._declare_many_to_one('substitution_template')
 
     @declared_attr
     def node_type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     @declared_attr
     def mappings(cls):
-        return cls._create_one_to_many_relationship('substitution_mapping', dict_key='name')
+        return cls._declare_one_to_many('substitution_mapping', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['node_type_fk',
-                          'substitution_template_fk']
-
-    # Substitution many-to-one to Type
     @declared_attr
     def node_type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Substitution many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Substitution many-to-one to SubstitutionTemplate
     @declared_attr
     def substitution_template_fk(cls):
-        return cls._create_foreign_key('substitution_template', nullable=True)
+        """For Substitution many-to-one to SubstitutionTemplate"""
+        return cls._declare_fk('substitution_template', nullable=True)
 
     # endregion
 
@@ -855,6 +840,9 @@ class SubstitutionBase(InstanceModelMixin):
             console.puts('Node type: {0}'.format(context.style.type(self.node_type.name)))
             utils.dump_dict_values(self.mappings, 'Mappings')
 
+    __private_fields__ = ['node_type_fk',
+                          'substitution_template_fk']
+
 
 class SubstitutionMappingBase(InstanceModelMixin):
     """
@@ -881,42 +869,37 @@ class SubstitutionMappingBase(InstanceModelMixin):
 
     @declared_attr
     def node(cls):
-        return cls._create_one_to_one_relationship('node')
+        return cls._declare_one_to_one('node')
 
     @declared_attr
     def capability(cls):
-        return cls._create_one_to_one_relationship('capability')
+        return cls._declare_one_to_one('capability')
 
     @declared_attr
     def requirement_template(cls):
-        return cls._create_one_to_one_relationship('requirement_template')
+        return cls._declare_one_to_one('requirement_template')
 
     # region foreign keys
 
-    __private_fields__ = ['substitution_fk',
-                          'node_fk',
-                          'capability_fk',
-                          'requirement_template_fk']
-
-    # Substitution one-to-many to SubstitutionMapping
     @declared_attr
     def substitution_fk(cls):
-        return cls._create_foreign_key('substitution')
+        """For Substitution one-to-many to SubstitutionMapping"""
+        return cls._declare_fk('substitution')
 
-    # Substitution one-to-one to NodeTemplate
     @declared_attr
     def node_fk(cls):
-        return cls._create_foreign_key('node')
+        """For Substitution one-to-one to NodeTemplate"""
+        return cls._declare_fk('node')
 
-    # Substitution one-to-one to Capability
     @declared_attr
     def capability_fk(cls):
-        return cls._create_foreign_key('capability', nullable=True)
+        """For Substitution one-to-one to Capability"""
+        return cls._declare_fk('capability', nullable=True)
 
-    # Substitution one-to-one to RequirementTemplate
     @declared_attr
     def requirement_template_fk(cls):
-        return cls._create_foreign_key('requirement_template', nullable=True)
+        """For Substitution one-to-one to RequirementTemplate"""
+        return cls._declare_fk('requirement_template', nullable=True)
 
     # endregion
 
@@ -943,6 +926,11 @@ class SubstitutionMappingBase(InstanceModelMixin):
                                if self.capability
                                else self.requirement_template.name)))
 
+    __private_fields__ = ['substitution_fk',
+                          'node_fk',
+                          'capability_fk',
+                          'requirement_template_fk']
+
 
 class RelationshipBase(InstanceModelMixin):
     """
@@ -982,28 +970,27 @@ class RelationshipBase(InstanceModelMixin):
 
     @declared_attr
     def relationship_template(cls):
-        return cls._create_many_to_one_relationship('relationship_template')
+        return cls._declare_many_to_one('relationship_template')
 
     @declared_attr
     def requirement_template(cls):
-        return cls._create_many_to_one_relationship('requirement_template')
+        return cls._declare_many_to_one('requirement_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     @declared_attr
     def target_capability(cls):
-        return cls._create_one_to_one_relationship('capability')
+        return cls._declare_one_to_one('capability')
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interfaces(cls):
-        return cls._create_one_to_many_relationship('interface', dict_key='name')
+        return cls._declare_one_to_many('interface', dict_key='name')
 
     # region orchestration
 
@@ -1014,42 +1001,49 @@ class RelationshipBase(InstanceModelMixin):
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'source_node_fk',
-                          'target_node_fk',
-                          'target_capability_fk',
-                          'requirement_template_fk',
-                          'relationship_template_fk']
-
-    # Relationship many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type', nullable=True)
+        """For Relationship many-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    # Node one-to-many to Relationship
     @declared_attr
     def source_node_fk(cls):
-        return cls._create_foreign_key('node')
+        """For Node one-to-many to Relationship"""
+        return cls._declare_fk('node')
 
-    # Node one-to-many to Relationship
     @declared_attr
     def target_node_fk(cls):
-        return cls._create_foreign_key('node')
+        """For Node one-to-many to Relationship"""
+        return cls._declare_fk('node')
 
-    # Relationship one-to-one to Capability
     @declared_attr
     def target_capability_fk(cls):
-        return cls._create_foreign_key('capability', nullable=True)
+        """For Relationship one-to-one to Capability"""
+        return cls._declare_fk('capability', nullable=True)
 
-    # Relationship many-to-one to RequirementTemplate
     @declared_attr
     def requirement_template_fk(cls):
-        return cls._create_foreign_key('requirement_template', nullable=True)
+        """For Relationship many-to-one to RequirementTemplate"""
+        return cls._declare_fk('requirement_template', nullable=True)
 
-    # Relationship many-to-one to RelationshipTemplate
     @declared_attr
     def relationship_template_fk(cls):
-        return cls._create_foreign_key('relationship_template', nullable=True)
+        """For Relationship many-to-one to RelationshipTemplate"""
+        return cls._declare_fk('relationship_template', nullable=True)
+
+    # endregion
+
+    # region association proxies
+
+    @declared_attr
+    def source_node_name(cls):
+        """Required for use by SqlAlchemy queries"""
+        return association_proxy('source_node', 'name')
+
+    @declared_attr
+    def target_node_name(cls):
+        """Required for use by SqlAlchemy queries"""
+        return association_proxy('target_node', 'name')
 
     # endregion
 
@@ -1058,8 +1052,10 @@ class RelationshipBase(InstanceModelMixin):
         return collections.OrderedDict((
             ('name', self.name),
             ('target_node_id', self.target_node.name),
-            ('type_name', self.type_name),
-            ('template_name', self.template_name),
+            ('type_name', self.type.name
+             if self.type is not None else None),
+            ('template_name', self.relationship_template.name
+             if self.relationship_template is not None else None),
             ('properties', formatting.as_raw_dict(self.properties)),
             ('interfaces', formatting.as_raw_list(self.interfaces))))
 
@@ -1090,6 +1086,15 @@ class RelationshipBase(InstanceModelMixin):
             utils.dump_dict_values(self.properties, 'Properties')
             utils.dump_interfaces(self.interfaces, 'Interfaces')
 
+    __private_fields__ = ['type_fk',
+                          'source_node_fk',
+                          'target_node_fk',
+                          'target_capability_fk',
+                          'requirement_template_fk',
+                          'relationship_template_fk',
+                          'source_node_name',
+                          'target_node_name']
+
 
 class CapabilityBase(InstanceModelMixin):
     """
@@ -1124,11 +1129,11 @@ class CapabilityBase(InstanceModelMixin):
 
     @declared_attr
     def capability_template(cls):
-        return cls._create_many_to_one_relationship('capability_template')
+        return cls._declare_many_to_one('capability_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     min_occurrences = Column(Integer, default=None)
     max_occurrences = Column(Integer, default=None)
@@ -1136,29 +1141,24 @@ class CapabilityBase(InstanceModelMixin):
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['capability_fk',
-                          'node_fk',
-                          'capability_template_fk']
-
-    # Capability many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Capability many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Node one-to-many to Capability
     @declared_attr
     def node_fk(cls):
-        return cls._create_foreign_key('node')
+        """For Node one-to-many to Capability"""
+        return cls._declare_fk('node')
 
-    # Capability many-to-one to CapabilityTemplate
     @declared_attr
     def capability_template_fk(cls):
-        return cls._create_foreign_key('capability_template', nullable=True)
+        """For Capability many-to-one to CapabilityTemplate"""
+        return cls._declare_fk('capability_template', nullable=True)
 
     # endregion
 
@@ -1179,7 +1179,7 @@ class CapabilityBase(InstanceModelMixin):
     def as_raw(self):
         return collections.OrderedDict((
             ('name', self.name),
-            ('type_name', self.type_name),
+            ('type_name', self.type.name),
             ('properties', formatting.as_raw_dict(self.properties))))
 
     def validate(self):
@@ -1201,6 +1201,10 @@ class CapabilityBase(InstanceModelMixin):
                 else ' or more'))
             utils.dump_dict_values(self.properties, 'Properties')
 
+    __private_fields__ = ['capability_fk',
+                          'node_fk',
+                          'capability_template_fk']
+
 
 class InterfaceBase(InstanceModelMixin):
     """
@@ -1233,55 +1237,48 @@ class InterfaceBase(InstanceModelMixin):
 
     @declared_attr
     def interface_template(cls):
-        return cls._create_many_to_one_relationship('interface_template')
+        return cls._declare_many_to_one('interface_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def inputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='inputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
 
     @declared_attr
     def operations(cls):
-        return cls._create_one_to_many_relationship('operation', dict_key='name')
+        return cls._declare_one_to_many('operation', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'node_fk',
-                          'group_fk',
-                          'relationship_fk',
-                          'interface_template_fk']
-
-    # Interface many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Interface many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Node one-to-many to Interface
     @declared_attr
     def node_fk(cls):
-        return cls._create_foreign_key('node', nullable=True)
+        """For Node one-to-many to Interface"""
+        return cls._declare_fk('node', nullable=True)
 
-    # Group one-to-many to Interface
     @declared_attr
     def group_fk(cls):
-        return cls._create_foreign_key('group', nullable=True)
+        """For Group one-to-many to Interface"""
+        return cls._declare_fk('group', nullable=True)
 
-    # Relationship one-to-many to Interface
     @declared_attr
     def relationship_fk(cls):
-        return cls._create_foreign_key('relationship', nullable=True)
+        """For Relationship one-to-many to Interface"""
+        return cls._declare_fk('relationship', nullable=True)
 
-    # Interface many-to-one to InterfaceTemplate
     @declared_attr
     def interface_template_fk(cls):
-        return cls._create_foreign_key('interface_template', nullable=True)
+        """For Interface many-to-one to InterfaceTemplate"""
+        return cls._declare_fk('interface_template', nullable=True)
 
     # endregion
 
@@ -1290,7 +1287,7 @@ class InterfaceBase(InstanceModelMixin):
         return collections.OrderedDict((
             ('name', self.name),
             ('description', self.description),
-            ('type_name', self.type_name),
+            ('type_name', self.type.name),
             ('inputs', formatting.as_raw_dict(self.inputs)),
             ('operations', formatting.as_raw_list(self.operations))))
 
@@ -1312,6 +1309,12 @@ class InterfaceBase(InstanceModelMixin):
             utils.dump_dict_values(self.inputs, 'Inputs')
             utils.dump_dict_values(self.operations, 'Operations')
 
+    __private_fields__ = ['type_fk',
+                          'node_fk',
+                          'group_fk',
+                          'relationship_fk',
+                          'interface_template_fk']
+
 
 class OperationBase(InstanceModelMixin):
     """
@@ -1350,21 +1353,20 @@ class OperationBase(InstanceModelMixin):
 
     @declared_attr
     def operation_template(cls):
-        return cls._create_many_to_one_relationship('operation_template')
+        return cls._declare_many_to_one('operation_template')
 
     description = Column(Text)
 
     @declared_attr
     def plugin_specification(cls):
-        return cls._create_one_to_one_relationship('plugin_specification')
+        return cls._declare_one_to_one('plugin_specification')
 
     implementation = Column(Text)
     dependencies = Column(modeling_types.StrictList(item_cls=basestring))
 
     @declared_attr
     def inputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='inputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
 
     executor = Column(Text)
     max_retries = Column(Integer)
@@ -1372,30 +1374,25 @@ class OperationBase(InstanceModelMixin):
 
     # region foreign_keys
 
-    __private_fields__ = ['service_fk',
-                          'interface_fk',
-                          'plugin_fk',
-                          'operation_template_fk']
-
-    # Service one-to-many to Operation
     @declared_attr
     def service_fk(cls):
-        return cls._create_foreign_key('service', nullable=True)
+        """For Service one-to-many to Operation"""
+        return cls._declare_fk('service', nullable=True)
 
-    # Interface one-to-many to Operation
     @declared_attr
     def interface_fk(cls):
-        return cls._create_foreign_key('interface', nullable=True)
+        """For Interface one-to-many to Operation"""
+        return cls._declare_fk('interface', nullable=True)
 
-    # Operation one-to-one to PluginSpecification
     @declared_attr
     def plugin_specification_fk(cls):
-        return cls._create_foreign_key('plugin_specification', nullable=True)
+        """For Operation one-to-one to PluginSpecification"""
+        return cls._declare_fk('plugin_specification', nullable=True)
 
-    # Operation many-to-one to OperationTemplate
     @declared_attr
     def operation_template_fk(cls):
-        return cls._create_foreign_key('operation_template', nullable=True)
+        """For Operation many-to-one to OperationTemplate"""
+        return cls._declare_fk('operation_template', nullable=True)
 
     # endregion
 
@@ -1440,6 +1437,11 @@ class OperationBase(InstanceModelMixin):
                     context.style.literal(self.retry_interval)))
             utils.dump_dict_values(self.inputs, 'Inputs')
 
+    __private_fields__ = ['service_fk',
+                          'interface_fk',
+                          'plugin_fk',
+                          'operation_template_fk']
+
 
 class ArtifactBase(InstanceModelMixin):
     """
@@ -1474,11 +1476,11 @@ class ArtifactBase(InstanceModelMixin):
 
     @declared_attr
     def artifact_template(cls):
-        return cls._create_many_to_one_relationship('artifact_template')
+        return cls._declare_many_to_one('artifact_template')
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
     source_path = Column(Text)
@@ -1488,29 +1490,24 @@ class ArtifactBase(InstanceModelMixin):
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'node_fk',
-                          'artifact_template_fk']
-
-    # Artifact many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For Artifact many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # Node one-to-many to Artifact
     @declared_attr
     def node_fk(cls):
-        return cls._create_foreign_key('node')
+        """For Node one-to-many to Artifact"""
+        return cls._declare_fk('node')
 
-    # Artifact many-to-one to ArtifactTemplate
     @declared_attr
     def artifact_template_fk(cls):
-        return cls._create_foreign_key('artifact_template', nullable=True)
+        """For Artifact many-to-one to ArtifactTemplate"""
+        return cls._declare_fk('artifact_template', nullable=True)
 
     # endregion
 
@@ -1519,7 +1516,7 @@ class ArtifactBase(InstanceModelMixin):
         return collections.OrderedDict((
             ('name', self.name),
             ('description', self.description),
-            ('type_name', self.type_name),
+            ('type_name', self.type.name),
             ('source_path', self.source_path),
             ('target_path', self.target_path),
             ('repository_url', self.repository_url),
@@ -1549,3 +1546,7 @@ class ArtifactBase(InstanceModelMixin):
                 console.puts('Repository credential: {0}'.format(
                     context.style.literal(self.repository_credential)))
             utils.dump_dict_values(self.properties, 'Properties')
+
+    __private_fields__ = ['type_fk',
+                          'node_fk',
+                          'artifact_template_fk']

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0f040a2b/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index d2d6c4b..b365720 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -27,6 +27,7 @@ from sqlalchemy import (
     DateTime
 )
 from sqlalchemy.ext.declarative import declared_attr
+from sqlalchemy.ext.associationproxy import association_proxy
 
 from ..parser import validation
 from ..parser.consumption import ConsumptionContext
@@ -38,8 +39,6 @@ from . import (
     types as modeling_types
 )
 
-from . import relationship
-
 
 class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public-methods
     """
@@ -57,11 +56,11 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
     :ivar meta_data: Custom annotations
     :vartype meta_data: {basestring: :class:`Metadata`}
     :ivar node_templates: Templates for creating nodes
-    :vartype node_templates: [:class:`NodeTemplate`]
+    :vartype node_templates: {basestring: :class:`NodeTemplate`}
     :ivar group_templates: Templates for creating groups
-    :vartype group_templates: [:class:`GroupTemplate`]
+    :vartype group_templates: {basestring: :class:`GroupTemplate`}
     :ivar policy_templates: Templates for creating policies
-    :vartype policy_templates: [:class:`PolicyTemplate`]
+    :vartype policy_templates: {basestring: :class:`PolicyTemplate`}
     :ivar substitution_template: The entire service can appear as a node
     :vartype substitution_template: :class:`SubstitutionTemplate`
     :ivar inputs: Externally provided parameters
@@ -102,70 +101,70 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
     description = Column(Text)
     main_file_name = Column(Text)
 
-    @relationship.many_to_many('metadata', dict_key='name')
+    @declared_attr
     def meta_data(cls):
         # Warning! We cannot use the attr name "metadata" because it's used by SqlAlchemy!
-        pass
+        return cls._declare_many_to_many('metadata', dict_key='name')
 
-    @relationship.one_to_many('node_template')
+    @declared_attr
     def node_templates(cls):
-        pass
+        return cls._declare_one_to_many('node_template', dict_key='name')
 
-    @relationship.one_to_many('group_template')
+    @declared_attr
     def group_templates(cls):
-        pass
+        return cls._declare_one_to_many('group_template', dict_key='name')
 
-    @relationship.one_to_many('policy_template')
+    @declared_attr
     def policy_templates(cls):
-        pass
+        return cls._declare_one_to_many('policy_template', dict_key='name')
 
-    @relationship.one_to_one('substitution_template')
+    @declared_attr
     def substitution_template(cls):
-        pass
+        return cls._declare_one_to_one('substitution_template')
 
-    @relationship.many_to_many('parameter', prefix='inputs', dict_key='name')
+    @declared_attr
     def inputs(cls):
-        pass
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
 
-    @relationship.many_to_many('parameter', prefix='outputs', dict_key='name')
+    @declared_attr
     def outputs(cls):
-        pass
+        return cls._declare_many_to_many('parameter', prefix='outputs', dict_key='name')
 
-    @relationship.one_to_many('operation_template', dict_key='name')
+    @declared_attr
     def workflow_templates(cls):
-        pass
+        return cls._declare_one_to_many('operation_template', dict_key='name')
 
-    @relationship.one_to_many('plugin_specification')
+    @declared_attr
     def plugin_specifications(cls):
-        pass
+        return cls._declare_one_to_many('plugin_specification', dict_key='name')
 
-    @relationship.one_to_one('type', fk='node_type_fk', other_property=False)
+    @declared_attr
     def node_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='node_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='group_type_fk', other_property=False)
+    @declared_attr
     def group_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='group_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='policy_type_fk', other_property=False)
+    @declared_attr
     def policy_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='policy_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='relationship_type_fk', other_property=False)
+    @declared_attr
     def relationship_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='relationship_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='capability_type_fk', other_property=False)
+    @declared_attr
     def capability_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='capability_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='interface_type_fk', other_property=False)
+    @declared_attr
     def interface_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='interface_type_fk', other_property=False)
 
-    @relationship.one_to_one('type', fk='artifact_type_fk', other_property=False)
+    @declared_attr
     def artifact_types(cls):
-        pass
+        return cls._declare_one_to_one('type', fk='artifact_type_fk', other_property=False)
 
     # region orchestration
 
@@ -176,54 +175,48 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
 
     # region foreign keys
 
-    @relationship.fk('substitution_template', nullable=True)
+    @declared_attr
     def substitution_template_fk(cls):
         """For ServiceTemplate one-to-one to SubstitutionTemplate"""
+        return cls._declare_fk('substitution_template', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def node_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def group_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def policy_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def relationship_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def capability_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def interface_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    @relationship.fk('type', nullable=True)
+    @declared_attr
     def artifact_type_fk(cls):
         """For ServiceTemplate one-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
     # endregion
 
-    def get_node_template(self, node_template_name):
-        if self.node_templates:
-            for node_template in self.node_templates:
-                if node_template.name == node_template_name:
-                    return node_template
-        return None
-
-    def get_group_template(self, group_template_name):
-        if self.group_templates:
-            for group_template in self.group_templates:
-                if group_template.name == group_template_name:
-                    return group_template
-        return None
-
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -262,13 +255,13 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
 
         utils.instantiate_dict(self, service.meta_data, self.meta_data)
 
-        for node_template in self.node_templates:
+        for node_template in self.node_templates.itervalues():
             for _ in range(node_template.default_instances):
                 node = node_template.instantiate(container)
-                service.nodes.append(node)
+                service.nodes[node.name] = node
 
-        utils.instantiate_list(self, service.groups, self.group_templates)
-        utils.instantiate_list(self, service.policies, self.policy_templates)
+        utils.instantiate_dict(self, service.groups, self.group_templates)
+        utils.instantiate_dict(self, service.policies, self.policy_templates)
         utils.instantiate_dict(self, service.workflows, self.workflow_templates)
 
         if self.substitution_template is not None:
@@ -287,9 +280,9 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
 
     def validate(self):
         utils.validate_dict_values(self.meta_data)
-        utils.validate_list_values(self.node_templates)
-        utils.validate_list_values(self.group_templates)
-        utils.validate_list_values(self.policy_templates)
+        utils.validate_dict_values(self.node_templates)
+        utils.validate_dict_values(self.group_templates)
+        utils.validate_dict_values(self.policy_templates)
         if self.substitution_template is not None:
             self.substitution_template.validate()
         utils.validate_dict_values(self.inputs)
@@ -312,9 +305,9 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
 
     def coerce_values(self, container, report_issues):
         utils.coerce_dict_values(container, self.meta_data, report_issues)
-        utils.coerce_list_values(container, self.node_templates, report_issues)
-        utils.coerce_list_values(container, self.group_templates, report_issues)
-        utils.coerce_list_values(container, self.policy_templates, report_issues)
+        utils.coerce_dict_values(container, self.node_templates, report_issues)
+        utils.coerce_dict_values(container, self.group_templates, report_issues)
+        utils.coerce_dict_values(container, self.policy_templates, report_issues)
         if self.substitution_template is not None:
             self.substitution_template.coerce_values(container, report_issues)
         utils.coerce_dict_values(container, self.inputs, report_issues)
@@ -322,19 +315,15 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
         utils.coerce_dict_values(container, self.workflow_templates, report_issues)
 
     def dump(self):
-        #print dir(self)
-        #from inspect import getdoc
-        #print getdoc(self.__class__.substitution_template_fk)
-        #exit()
         context = ConsumptionContext.get_thread_local()
         if self.description is not None:
             console.puts(context.style.meta(self.description))
         utils.dump_dict_values(self.meta_data, 'Metadata')
-        for node_template in self.node_templates:
+        for node_template in self.node_templates.itervalues():
             node_template.dump()
-        for group_template in self.group_templates:
+        for group_template in self.group_templates.itervalues():
             group_template.dump()
-        for policy_template in self.policy_templates:
+        for policy_template in self.policy_templates.itervalues():
             policy_template.dump()
         if self.substitution_template is not None:
             self.substitution_template.dump()
@@ -365,6 +354,15 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public
             console.puts('Interface types:')
             self.interface_types.dump()
 
+    __private_fields__ = ['substitution_template_fk',
+                          'node_type_fk',
+                          'group_type_fk',
+                          'policy_type_fk',
+                          'relationship_type_fk',
+                          'capability_type_fk',
+                          'interface_type_fk',
+                          'artifact_type_fk']
+
 
 class NodeTemplateBase(TemplateModelMixin):
     """
@@ -414,7 +412,7 @@ class NodeTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
     default_instances = Column(Integer, default=1)
@@ -423,47 +421,51 @@ class NodeTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interface_templates(cls):
-        return cls._create_one_to_many_relationship('interface_template', dict_key='name')
+        return cls._declare_one_to_many('interface_template', dict_key='name')
 
     @declared_attr
     def artifact_templates(cls):
-        return cls._create_one_to_many_relationship('artifact_template', dict_key='name')
+        return cls._declare_one_to_many('artifact_template', dict_key='name')
 
     @declared_attr
     def capability_templates(cls):
-        return cls._create_one_to_many_relationship('capability_template', dict_key='name')
+        return cls._declare_one_to_many('capability_template', dict_key='name')
 
     @declared_attr
     def requirement_templates(cls):
-        return cls._create_one_to_many_relationship('requirement_template',
-                                                    foreign_key='node_template_fk',
-                                                    backreference='node_template')
+        return cls._declare_one_to_many('requirement_template', child_fk='node_template_fk',
+                                        child_property='node_template')
 
     target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
 
     @declared_attr
     def plugin_specifications(cls):
-        return cls._create_many_to_many_relationship('plugin_specification')
+        return cls._declare_many_to_many('plugin_specification', dict_key='name')
 
     # region foreign_keys
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
-
-    # NodeTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For NodeTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # ServiceTemplate one-to-many to NodeTemplate
     @declared_attr
     def service_template_fk(cls):
-        return cls._create_foreign_key('service_template')
+        """For ServiceTemplate one-to-many to NodeTemplate"""
+        return cls._declare_fk('service_template')
+
+    # endregion
+
+    # region association proxies
+
+    @declared_attr
+    def service_template_name(cls):
+        """Required for use by SqlAlchemy queries"""
+        return association_proxy('service_template', 'name')
 
     # endregion
 
@@ -537,6 +539,10 @@ class NodeTemplateBase(TemplateModelMixin):
             utils.dump_dict_values(self.capability_templates, 'Capability templates')
             utils.dump_list_values(self.requirement_templates, 'Requirement templates')
 
+    __private_fields__ = ['type_fk',
+                          'service_template_fk',
+                          'service_template_name']
+
 
 class GroupTemplateBase(TemplateModelMixin):
     """
@@ -569,37 +575,33 @@ class GroupTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def node_templates(cls):
-        return cls._create_many_to_many_relationship('node_template')
+        return cls._declare_many_to_many('node_template')
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interface_templates(cls):
-        return cls._create_one_to_many_relationship('interface_template', dict_key='name')
+        return cls._declare_one_to_many('interface_template', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
-
-    # GroupTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For GroupTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # ServiceTemplate one-to-many to GroupTemplate
     @declared_attr
     def service_template_fk(cls):
-        return cls._create_foreign_key('service_template')
+        """For ServiceTemplate one-to-many to GroupTemplate"""
+        return cls._declare_fk('service_template')
 
     # endregion
 
@@ -646,6 +648,9 @@ class GroupTemplateBase(TemplateModelMixin):
                 console.puts('Member node templates: {0}'.format(', '.join(
                     (str(context.style.node(v.name)) for v in self.node_templates))))
 
+    __private_fields__ = ['type_fk',
+                          'service_template_fk']
+
 
 class PolicyTemplateBase(TemplateModelMixin):
     """
@@ -675,37 +680,33 @@ class PolicyTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def node_templates(cls):
-        return cls._create_many_to_many_relationship('node_template')
+        return cls._declare_many_to_many('node_template')
 
     @declared_attr
     def group_templates(cls):
-        return cls._create_many_to_many_relationship('group_template')
+        return cls._declare_many_to_many('group_template')
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
-
-    # PolicyTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For PolicyTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # ServiceTemplate one-to-many to PolicyTemplate
     @declared_attr
     def service_template_fk(cls):
-        return cls._create_foreign_key('service_template')
+        """For ServiceTemplate one-to-many to PolicyTemplate"""
+        return cls._declare_fk('service_template')
 
     # endregion
 
@@ -753,6 +754,9 @@ class PolicyTemplateBase(TemplateModelMixin):
                 console.puts('Target group templates: {0}'.format(', '.join(
                     (str(context.style.node(v.name)) for v in self.group_templates))))
 
+    __private_fields__ = ['type_fk',
+                          'service_template_fk']
+
 
 class SubstitutionTemplateBase(TemplateModelMixin):
     """
@@ -773,21 +777,18 @@ class SubstitutionTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def node_type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     @declared_attr
     def mappings(cls):
-        return cls._create_one_to_many_relationship('substitution_template_mapping',
-                                                    dict_key='name')
+        return cls._declare_one_to_many('substitution_template_mapping', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['node_type_fk']
-
-    # SubstitutionTemplate many-to-one to Type
     @declared_attr
     def node_type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For SubstitutionTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
     # endregion
 
@@ -817,6 +818,8 @@ class SubstitutionTemplateBase(TemplateModelMixin):
             console.puts('Node type: {0}'.format(context.style.type(self.node_type.name)))
             utils.dump_dict_values(self.mappings, 'Mappings')
 
+    __private_fields__ = ['node_type_fk']
+
 
 class SubstitutionTemplateMappingBase(TemplateModelMixin):
     """
@@ -841,42 +844,37 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
 
     @declared_attr
     def node_template(cls):
-        return cls._create_one_to_one_relationship('node_template')
+        return cls._declare_one_to_one('node_template')
 
     @declared_attr
     def capability_template(cls):
-        return cls._create_one_to_one_relationship('capability_template')
+        return cls._declare_one_to_one('capability_template')
 
     @declared_attr
     def requirement_template(cls):
-        return cls._create_one_to_one_relationship('requirement_template')
+        return cls._declare_one_to_one('requirement_template')
 
     # region foreign keys
 
-    __private_fields__ = ['substitution_template_fk',
-                          'node_template_fk',
-                          'capability_template_fk',
-                          'requirement_template_fk']
-
-    # SubstitutionTemplate one-to-many to SubstitutionTemplateMapping
     @declared_attr
     def substitution_template_fk(cls):
-        return cls._create_foreign_key('substitution_template')
+        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
+        return cls._declare_fk('substitution_template')
 
-    # SubstitutionTemplate one-to-one to NodeTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template')
+        """For SubstitutionTemplate one-to-one to NodeTemplate"""
+        return cls._declare_fk('node_template')
 
-    # SubstitutionTemplate one-to-one to CapabilityTemplate
     @declared_attr
     def capability_template_fk(cls):
-        return cls._create_foreign_key('capability_template', nullable=True)
+        """For SubstitutionTemplate one-to-one to CapabilityTemplate"""
+        return cls._declare_fk('capability_template', nullable=True)
 
-    # SubstitutionTemplate one-to-one to RequirementTemplate
     @declared_attr
     def requirement_template_fk(cls):
-        return cls._create_foreign_key('requirement_template', nullable=True)
+        """For SubstitutionTemplate one-to-one to RequirementTemplate"""
+        return cls._declare_fk('requirement_template', nullable=True)
 
     # endregion
 
@@ -888,15 +886,15 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
     def instantiate(self, container):
         from . import models
         context = ConsumptionContext.get_thread_local()
-        nodes = context.modeling.instance.find_nodes(self.node_template.name)
+        nodes = self.node_template.nodes.all()
         if len(nodes) == 0:
             context.validation.report(
                 'mapping "{0}" refers to node template "{1}" but there are no '
                 'node instances'.format(self.mapped_name, self.node_template.name),
                 level=validation.Issue.BETWEEN_INSTANCES)
             return None
-        # The TOSCA spec does not provide a way to choose the node, so we will just pick the first
-        # one
+        # The TOSCA spec does not provide a way to choose the node,
+        # so we will just pick the first one
         node = nodes[0]
         capability = None
         if self.capability_template:
@@ -926,6 +924,11 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
                                if self.capability_template
                                else self.requirement_template.name)))
 
+    __private_fields__ = ['substitution_template_fk',
+                          'node_template_fk',
+                          'capability_template_fk',
+                          'requirement_template_fk']
+
 
 class RequirementTemplateBase(TemplateModelMixin):
     """
@@ -962,58 +965,50 @@ class RequirementTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def target_node_type(cls):
-        return cls._create_many_to_one_relationship('type', key='target_node_type_fk',
-                                                    backreference=False)
+        return cls._declare_many_to_one('type', fk='target_node_type_fk', parent_property=False)
 
     @declared_attr
     def target_node_template(cls):
-        return cls._create_one_to_one_relationship('node_template', key='target_node_template_fk',
-                                                   backreference=False)
+        return cls._declare_one_to_one('node_template', fk='target_node_template_fk',
+                                       other_property=False)
 
     @declared_attr
     def target_capability_type(cls):
-        return cls._create_one_to_one_relationship('type', key='target_capability_type_fk',
-                                                   backreference=False)
+        return cls._declare_one_to_one('type', fk='target_capability_type_fk', other_property=False)
 
     target_capability_name = Column(Text)
     target_node_template_constraints = Column(modeling_types.StrictList(FunctionType))
 
     @declared_attr
     def relationship_template(cls):
-        return cls._create_one_to_one_relationship('relationship_template')
+        return cls._declare_one_to_one('relationship_template')
 
     # region foreign keys
 
-    __private_fields__ = ['target_node_type_fk',
-                          'target_node_template_fk',
-                          'target_capability_type_fk'
-                          'node_template_fk',
-                          'relationship_template_fk']
-
-    # RequirementTemplate many-to-one to Type
     @declared_attr
     def target_node_type_fk(cls):
-        return cls._create_foreign_key('type', nullable=True)
+        """For RequirementTemplate many-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
-    # RequirementTemplate one-to-one to NodeTemplate
     @declared_attr
     def target_node_template_fk(cls):
-        return cls._create_foreign_key('node_template', nullable=True)
+        """For RequirementTemplate one-to-one to NodeTemplate"""
+        return cls._declare_fk('node_template', nullable=True)
 
-    # RequirementTemplate one-to-one to NodeTemplate
     @declared_attr
     def target_capability_type_fk(cls):
-        return cls._create_foreign_key('type', nullable=True)
+        """For RequirementTemplate one-to-one to NodeTemplate"""
+        return cls._declare_fk('type', nullable=True)
 
-    # NodeTemplate one-to-many to RequirementTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template')
+        """For NodeTemplate one-to-many to RequirementTemplate"""
+        return cls._declare_fk('node_template')
 
-    # RequirementTemplate one-to-one to RelationshipTemplate
     @declared_attr
     def relationship_template_fk(cls):
-        return cls._create_foreign_key('relationship_template', nullable=True)
+        """For RequirementTemplate one-to-one to RelationshipTemplate"""
+        return cls._declare_fk('relationship_template', nullable=True)
 
     # endregion
 
@@ -1042,7 +1037,7 @@ class RequirementTemplateBase(TemplateModelMixin):
 
         # Find first node that matches the type
         elif self.target_node_type is not None:
-            for target_node_template in context.modeling.template.node_templates:
+            for target_node_template in context.modeling.template.node_templates.itervalues():
                 if self.target_node_type.get_descendant(target_node_template.type.name) is None:
                     continue
 
@@ -1070,9 +1065,12 @@ class RequirementTemplateBase(TemplateModelMixin):
     def as_raw(self):
         return collections.OrderedDict((
             ('name', self.name),
-            ('target_node_type_name', self.target_node_type.name),
-            ('target_node_template_name', self.target_node_template_name),
-            ('target_capability_type_name', self.target_capability_type_name),
+            ('target_node_type_name', self.target_node_type.name
+             if self.target_node_type is not None else None),
+            ('target_node_template_name', self.target_node_template.name
+             if self.target_node_template is not None else None),
+            ('target_capability_type_name', self.target_capability_type.name
+             if self.target_capability_type is not None else None),
             ('target_capability_name', self.target_capability_name),
             ('relationship_template', formatting.as_raw(self.relationship_template))))
 
@@ -1113,6 +1111,12 @@ class RequirementTemplateBase(TemplateModelMixin):
                 with context.style.indent:
                     self.relationship_template.dump()
 
+    __private_fields__ = ['target_node_type_fk',
+                          'target_node_template_fk',
+                          'target_capability_type_fk'
+                          'node_template_fk',
+                          'relationship_template_fk']
+
 
 class RelationshipTemplateBase(TemplateModelMixin):
     """
@@ -1144,27 +1148,24 @@ class RelationshipTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     @declared_attr
     def interface_templates(cls):
-        return cls._create_one_to_many_relationship('interface_template', dict_key='name')
+        return cls._declare_one_to_many('interface_template', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk']
-
-    # RelationshipTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type', nullable=True)
+        """For RelationshipTemplate many-to-one to Type"""
+        return cls._declare_fk('type', nullable=True)
 
     # endregion
 
@@ -1209,6 +1210,8 @@ class RelationshipTemplateBase(TemplateModelMixin):
             utils.dump_dict_values(self.properties, 'Properties')
             utils.dump_interfaces(self.interface_templates, 'Interface templates')
 
+    __private_fields__ = ['type_fk']
+
 
 class CapabilityTemplateBase(TemplateModelMixin):
     """
@@ -1242,7 +1245,7 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
     min_occurrences = Column(Integer, default=None)  # optional
@@ -1250,27 +1253,23 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def valid_source_node_types(cls):
-        return cls._create_many_to_many_relationship('type', table_prefix='valid_sources')
+        return cls._declare_many_to_many('type', prefix='valid_sources')
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
-
-    # CapabilityTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For CapabilityTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # NodeTemplate one-to-many to CapabilityTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template')
+        """For NodeTemplate one-to-many to CapabilityTemplate"""
+        return cls._declare_fk('node_template')
 
     # endregion
 
@@ -1305,7 +1304,7 @@ class CapabilityTemplateBase(TemplateModelMixin):
             ('type_name', self.type.name),
             ('min_occurrences', self.min_occurrences),
             ('max_occurrences', self.max_occurrences),
-            ('valid_source_node_type_names', self.valid_source_node_type_names),
+            ('valid_source_node_types', [v.name for v in self.valid_source_node_types]),
             ('properties', formatting.as_raw_dict(self.properties))))
 
     def instantiate(self, container):
@@ -1344,6 +1343,9 @@ class CapabilityTemplateBase(TemplateModelMixin):
                                for v in self.valid_source_node_types))))
             utils.dump_dict_values(self.properties, 'Properties')
 
+    __private_fields__ = ['type_fk',
+                          'node_template_fk']
+
 
 class InterfaceTemplateBase(TemplateModelMixin):
     """
@@ -1374,44 +1376,39 @@ class InterfaceTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
 
     @declared_attr
     def inputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='inputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
+
     @declared_attr
     def operation_templates(cls):
-        return cls._create_one_to_many_relationship('operation_template', dict_key='name')
+        return cls._declare_one_to_many('operation_template', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk',
-                          'group_template_fk',
-                          'relationship_template_fk']
-
-    # InterfaceTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For InterfaceTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # NodeTemplate one-to-many to InterfaceTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template', nullable=True)
+        """For NodeTemplate one-to-many to InterfaceTemplate"""
+        return cls._declare_fk('node_template', nullable=True)
 
-    # GroupTemplate one-to-many to InterfaceTemplate
     @declared_attr
     def group_template_fk(cls):
-        return cls._create_foreign_key('group_template', nullable=True)
+        """For GroupTemplate one-to-many to InterfaceTemplate"""
+        return cls._declare_fk('group_template', nullable=True)
 
-    # RelationshipTemplate one-to-many to InterfaceTemplate
     @declared_attr
     def relationship_template_fk(cls):
-        return cls._create_foreign_key('relationship_template', nullable=True)
+        """For RelationshipTemplate one-to-many to InterfaceTemplate"""
+        return cls._declare_fk('relationship_template', nullable=True)
 
     # endregion
 
@@ -1453,6 +1450,11 @@ class InterfaceTemplateBase(TemplateModelMixin):
             utils.dump_dict_values(self.inputs, 'Inputs')
             utils.dump_dict_values(self.operation_templates, 'Operation templates')
 
+    __private_fields__ = ['type_fk',
+                          'node_template_fk',
+                          'group_template_fk',
+                          'relationship_template_fk']
+
 
 class OperationTemplateBase(TemplateModelMixin):
     """
@@ -1493,15 +1495,14 @@ class OperationTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def plugin_specification(cls):
-        return cls._create_one_to_one_relationship('plugin_specification')
+        return cls._declare_one_to_one('plugin_specification')
 
     implementation = Column(Text)
     dependencies = Column(modeling_types.StrictList(item_cls=basestring))
 
     @declared_attr
     def inputs(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='inputs',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='inputs', dict_key='name')
 
     executor = Column(Text)
     max_retries = Column(Integer)
@@ -1509,24 +1510,20 @@ class OperationTemplateBase(TemplateModelMixin):
 
     # region foreign keys
 
-    __private_fields__ = ['service_template_fk',
-                          'interface_template_fk',
-                          'plugin_fk']
-
-    # ServiceTemplate one-to-many to OperationTemplate
     @declared_attr
     def service_template_fk(cls):
-        return cls._create_foreign_key('service_template', nullable=True)
+        """For ServiceTemplate one-to-many to OperationTemplate"""
+        return cls._declare_fk('service_template', nullable=True)
 
-    # InterfaceTemplate one-to-many to OperationTemplate
     @declared_attr
     def interface_template_fk(cls):
-        return cls._create_foreign_key('interface_template', nullable=True)
+        """For InterfaceTemplate one-to-many to OperationTemplate"""
+        return cls._declare_fk('interface_template', nullable=True)
 
-    # OperationTemplate one-to-one to PluginSpecification
     @declared_attr
     def plugin_specification_fk(cls):
-        return cls._create_foreign_key('plugin_specification', nullable=True)
+        """For OperationTemplate one-to-one to PluginSpecification"""
+        return cls._declare_fk('plugin_specification', nullable=True)
 
     # endregion
 
@@ -1583,6 +1580,10 @@ class OperationTemplateBase(TemplateModelMixin):
                     context.style.literal(self.retry_interval)))
             utils.dump_dict_values(self.inputs, 'Inputs')
 
+    __private_fields__ = ['service_template_fk',
+                          'interface_template_fk',
+                          'plugin_fk']
+
 
 class ArtifactTemplateBase(TemplateModelMixin):
     """
@@ -1615,7 +1616,7 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def type(cls):
-        return cls._create_many_to_one_relationship('type')
+        return cls._declare_many_to_one('type')
 
     description = Column(Text)
     source_path = Column(Text)
@@ -1625,23 +1626,19 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
     @declared_attr
     def properties(cls):
-        return cls._create_many_to_many_relationship('parameter', table_prefix='properties',
-                                                     dict_key='name')
+        return cls._declare_many_to_many('parameter', prefix='properties', dict_key='name')
 
     # region foreign keys
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
-
-    # ArtifactTemplate many-to-one to Type
     @declared_attr
     def type_fk(cls):
-        return cls._create_foreign_key('type')
+        """For ArtifactTemplate many-to-one to Type"""
+        return cls._declare_fk('type')
 
-    # NodeTemplate one-to-many to ArtifactTemplate
     @declared_attr
     def node_template_fk(cls):
-        return cls._create_foreign_key('node_template')
+        """For NodeTemplate one-to-many to ArtifactTemplate"""
+        return cls._declare_fk('node_template')
 
     # endregion
 
@@ -1693,3 +1690,6 @@ class ArtifactTemplateBase(TemplateModelMixin):
                 console.puts('Repository credential: {0}'.format(
                     context.style.literal(self.repository_credential)))
             utils.dump_dict_values(self.properties, 'Properties')
+
+    __private_fields__ = ['type_fk',
+                          'node_template_fk']

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0f040a2b/aria/modeling/types.py
----------------------------------------------------------------------
diff --git a/aria/modeling/types.py b/aria/modeling/types.py
index 10a58a7..90a1773 100644
--- a/aria/modeling/types.py
+++ b/aria/modeling/types.py
@@ -23,7 +23,7 @@ from sqlalchemy import (
 )
 from sqlalchemy.ext import mutable
 
-from ..storage import exceptions
+from . import exceptions
 
 
 class _MutableType(TypeDecorator):
@@ -78,7 +78,7 @@ class _StrictDictMixin(object):
             else:
                 return value
         except ValueError as e:
-            raise exceptions.StorageError('SQL Storage error: {0}'.format(str(e)))
+            raise exceptions.ValueFormatException('could not coerce to MutableDict', cause=e)
 
     def __setitem__(self, key, value):
         self._assert_strict_key(key)
@@ -99,16 +99,14 @@ class _StrictDictMixin(object):
     @classmethod
     def _assert_strict_key(cls, key):
         if cls._key_cls is not None and not isinstance(key, cls._key_cls):
-            raise exceptions.StorageError("Key type was set strictly to {0}, but was {1}".format(
-                cls._key_cls, type(key)
-            ))
+            raise exceptions.ValueFormatException('key type was set strictly to {0}, but was {1}'
+                                                  .format(cls._key_cls, type(key)))
 
     @classmethod
     def _assert_strict_value(cls, value):
         if cls._value_cls is not None and not isinstance(value, cls._value_cls):
-            raise exceptions.StorageError("Value type was set strictly to {0}, but was {1}".format(
-                cls._value_cls, type(value)
-            ))
+            raise exceptions.ValueFormatException('value type was set strictly to {0}, but was {1}'
+                                                  .format(cls._value_cls, type(value)))
 
 
 class _MutableDict(mutable.MutableDict):
@@ -122,7 +120,7 @@ class _MutableDict(mutable.MutableDict):
         try:
             return mutable.MutableDict.coerce(key, value)
         except ValueError as e:
-            raise exceptions.StorageError('SQL Storage error: {0}'.format(str(e)))
+            raise exceptions.ValueFormatException('could not coerce value', cause=e)
 
 
 class _StrictListMixin(object):
@@ -140,7 +138,7 @@ class _StrictListMixin(object):
             else:
                 return value
         except ValueError as e:
-            raise exceptions.StorageError('SQL Storage error: {0}'.format(str(e)))
+            raise exceptions.ValueFormatException('could not coerce to MutableDict', cause=e)
 
     def __setitem__(self, index, value):
         """Detect list set events and emit change events."""
@@ -162,9 +160,8 @@ class _StrictListMixin(object):
     @classmethod
     def _assert_item(cls, item):
         if cls._item_cls is not None and not isinstance(item, cls._item_cls):
-            raise exceptions.StorageError("Key type was set strictly to {0}, but was {1}".format(
-                cls._item_cls, type(item)
-            ))
+            raise exceptions.ValueFormatException('key type was set strictly to {0}, but was {1}'
+                                                  .format(cls._item_cls, type(item)))
 
 
 class _MutableList(mutable.MutableList):
@@ -175,13 +172,12 @@ class _MutableList(mutable.MutableList):
         try:
             return mutable.MutableList.coerce(key, value)
         except ValueError as e:
-            raise exceptions.StorageError('SQL Storage error: {0}'.format(str(e)))
+            raise exceptions.ValueFormatException('could not coerce to MutableDict', cause=e)
 
 
 _StrictDictID = namedtuple('_StrictDictID', 'key_cls, value_cls')
 _StrictValue = namedtuple('_StrictValue', 'type_cls, listener_cls')
 
-
 class _StrictDict(object):
     """
     This entire class functions as a factory for strict dicts and their listeners.
@@ -195,7 +191,7 @@ class _StrictDict(object):
         if strict_dict_map_key not in self._strict_map:
             key_cls_name = getattr(key_cls, '__name__', str(key_cls))
             value_cls_name = getattr(value_cls, '__name__', str(value_cls))
-            # Creating the type class itself. this class would be returned (used by the sqlalchemy
+            # Creating the type class itself. this class would be returned (used by the SqlAlchemy
             # Column).
             strict_dict_cls = type(
                 'StrictDict_{0}_{1}'.format(key_cls_name, value_cls_name),
@@ -231,7 +227,7 @@ class _StrictList(object):
 
         if item_cls not in self._strict_map:
             item_cls_name = getattr(item_cls, '__name__', str(item_cls))
-            # Creating the type class itself. this class would be returned (used by the sqlalchemy
+            # Creating the type class itself. this class would be returned (used by the SqlAlchemy
             # Column).
             strict_list_cls = type(
                 'StrictList_{0}'.format(item_cls_name),