Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-132-Models-cascading-deletion-raises-constraint-errors 5e70a4a3d -> f86477e1f (forced update)
ARIA-132-Models-cascading-deletion-raises-constraint-errors Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/f86477e1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/f86477e1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/f86477e1 Branch: refs/heads/ARIA-132-Models-cascading-deletion-raises-constraint-errors Commit: f86477e1f1d3b13b5ee423da4fdc5214e658875c Parents: b3cf69a Author: max-orlov <[email protected]> Authored: Sun Mar 26 14:13:47 2017 +0300 Committer: max-orlov <[email protected]> Committed: Mon Mar 27 14:35:51 2017 +0300 ---------------------------------------------------------------------- aria/.pylintrc | 2 +- aria/modeling/orchestration.py | 16 ++ aria/modeling/relationship.py | 201 ++++++++----------- aria/modeling/service_changes.py | 15 +- aria/modeling/service_common.py | 4 + aria/modeling/service_instance.py | 111 ++++++++-- aria/modeling/service_template.py | 151 +++++++++++--- tests/orchestrator/context/test_operation.py | 4 +- .../node-cellar/node-cellar.yaml | 1 - 9 files changed, 333 insertions(+), 172 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/.pylintrc ---------------------------------------------------------------------- diff --git a/aria/.pylintrc b/aria/.pylintrc index 589402f..7222605 100644 --- a/aria/.pylintrc +++ b/aria/.pylintrc @@ -375,7 +375,7 @@ max-attributes=20 min-public-methods=0 # Maximum number of public methods for a class (see R0904). -max-public-methods=20 +max-public-methods=50 # Maximum number of boolean expressions in a if statement max-bool-expr=5 http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/orchestration.py ---------------------------------------------------------------------- diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py index 2d58671..a13ae87 100644 --- a/aria/modeling/orchestration.py +++ b/aria/modeling/orchestration.py @@ -103,9 +103,17 @@ class ExecutionBase(ModelMixin): workflow_name = Column(Text) @declared_attr + def logs(cls): + return relationship.one_to_many(cls, 'log') + + @declared_attr def service(cls): return relationship.many_to_one(cls, 'service') + @declared_attr + def tasks(cls): + return relationship.one_to_many(cls, 'task') + # region foreign keys @declared_attr @@ -185,6 +193,10 @@ class PluginBase(ModelMixin): __tablename__ = 'plugin' + @declared_attr + def tasks(cls): + return relationship.one_to_many(cls, 'task') + archive_name = Column(Text, nullable=False, index=True) distribution = Column(Text) distribution_release = Column(Text) @@ -239,6 +251,10 @@ class TaskBase(ModelMixin): INFINITE_RETRIES = -1 @declared_attr + def logs(cls): + return relationship.one_to_many(cls, 'log') + + @declared_attr def node(cls): return relationship.many_to_one(cls, 'node') http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/relationship.py ---------------------------------------------------------------------- diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py index ef2bcdd..459c355 100644 --- a/aria/modeling/relationship.py +++ b/aria/modeling/relationship.py @@ -27,8 +27,7 @@ from sqlalchemy import ( from ..utils import formatting -def foreign_key(other_table, - nullable=False): +def foreign_key(other_table, nullable=False): """ Declare a foreign key property, which will also create a foreign key column in the table with the name of the property. By convention the property name should end in "_fk". @@ -54,9 +53,7 @@ def foreign_key(other_table, nullable=nullable) -def one_to_one_self(model_class, - fk, - relationship_kwargs=None): +def one_to_one_self(model_class, fk): """ Declare a one-to-one relationship property. The property value would be an instance of the same model. @@ -69,12 +66,8 @@ def one_to_one_self(model_class, :type model_class: type :param fk: Foreign key name :type fk: basestring - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} """ - relationship_kwargs = relationship_kwargs or {} - remote_side = '{model_class}.{remote_column}'.format( model_class=model_class.__name__, remote_column=model_class.id_column_name() @@ -91,14 +84,10 @@ def one_to_one_self(model_class, primaryjoin=primaryjoin, remote_side=remote_side, post_update=True, - **relationship_kwargs ) -def one_to_many_self(model_class, - fk, - dict_key=None, - relationship_kwargs=None): +def one_to_many_self(model_class, fk, dict_key=None): """ Declare a one-to-many relationship property. The property value would be a list or dict of instances of the same model. @@ -114,28 +103,25 @@ def one_to_many_self(model_class, :param dict_key: If set the value will be a dict with this key as the dict key; otherwise will be a list :type dict_key: basestring - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} """ - - relationship_kwargs = relationship_kwargs or {} - - relationship_kwargs.setdefault('remote_side', '{model_class}.{remote_column}'.format( - model_class=model_class.__name__, - remote_column=fk - )) - - return _relationship(model_class, model_class.__tablename__, None, relationship_kwargs, - other_property=False, dict_key=dict_key) + return _relationship( + model_class, + model_class.__tablename__, + relationship_kwargs={ + 'remote_side': '{model_class}.{remote_column}'.format(model_class=model_class.__name__, + remote_column=fk + ) + }, + back_populates=False, + dict_key=dict_key + ) def one_to_one(model_class, other_table, fk=None, other_fk=None, - other_property=None, - relationship_kwargs=None, - backref_kwargs=None): + back_populates=None): """ Declare a one-to-one relationship property. The property value would be an instance of the other table's model. @@ -154,26 +140,23 @@ def one_to_one(model_class, :type fk: basestring :param other_fk: Foreign key name at the other table (no need specify if there's no ambiguity) :type other_fk: basestring - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} - :param backref_kwargs: Extra kwargs for SQLAlchemy ``backref`` - :type backref_kwargs: {} + :param back_populates: Override name of matching many-to-many property at other table; set to + false to disable + :type back_populates: basestring|bool """ - backref_kwargs = backref_kwargs or {} - backref_kwargs.setdefault('uselist', False) - - return _relationship(model_class, other_table, backref_kwargs, relationship_kwargs, - other_property, fk=fk, other_fk=other_fk) + return _relationship(model_class, + other_table, + fk=fk, + back_populates=back_populates, + other_fk=other_fk) def one_to_many(model_class, child_table, child_fk=None, dict_key=None, - child_property=None, - relationship_kwargs=None, - backref_kwargs=None): + child_property=None): """ Declare a one-to-many relationship property. The property value would be a list or dict of instances of the child table's model. @@ -197,26 +180,20 @@ def one_to_many(model_class, :param child_property: Override name of matching many-to-one property at child table; set to false to disable :type child_property: basestring|bool - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} - :param backref_kwargs: Extra kwargs for SQLAlchemy ``backref`` - :type backref_kwargs: {} """ - - backref_kwargs = backref_kwargs or {} - backref_kwargs.setdefault('uselist', False) - - return _relationship(model_class, child_table, backref_kwargs, relationship_kwargs, - child_property, other_fk=child_fk, dict_key=dict_key) + return _relationship( + model_class, + child_table, + relationship_kwargs={'back_populates': child_property or model_class.__tablename__}, + other_fk=child_fk, + dict_key=dict_key) def many_to_one(model_class, parent_table, fk=None, parent_fk=None, - parent_property=None, - relationship_kwargs=None, - backref_kwargs=None): + back_populates=None): """ Declare a many-to-one relationship property. The property value would be an instance of the parent table's model. @@ -236,34 +213,27 @@ def many_to_one(model_class, :type parent_table: basestring :param fk: Foreign key name at our table (no need specify if there's no ambiguity) :type fk: basestring - :param parent_property: Override name of matching one-to-many property at parent table; set to + :param back_populates: Override name of matching one-to-many property at parent table; set to false to disable - :type parent_property: basestring|bool - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} - :param backref_kwargs: Extra kwargs for SQLAlchemy ``backref`` - :type backref_kwargs: {} + :type back_populates: basestring|bool """ + relationship_kwargs = {} + if back_populates is not False: + relationship_kwargs['back_populates'] = back_populates or \ + formatting.pluralize(model_class.__tablename__) - if parent_property is None: - parent_property = formatting.pluralize(model_class.__tablename__) - - backref_kwargs = backref_kwargs or {} - backref_kwargs.setdefault('uselist', True) - backref_kwargs.setdefault('lazy', 'dynamic') - backref_kwargs.setdefault('cascade', 'all') # delete children when parent is deleted - - return _relationship(model_class, parent_table, backref_kwargs, relationship_kwargs, - parent_property, fk=fk, other_fk=parent_fk) + return _relationship(model_class, + parent_table, + relationship_kwargs=relationship_kwargs, + fk=fk, + other_fk=parent_fk) def many_to_many(model_class, other_table, prefix=None, dict_key=None, - other_property=None, - relationship_kwargs=None, - backref_kwargs=None): + other_property=None): """ Declare a many-to-many relationship property. The property value would be a list or dict of instances of the other table's model. @@ -280,8 +250,8 @@ def many_to_many(model_class, :param model_class: The class in which this relationship will be declared :type model_class: type - :param parent_table: Parent table name - :type parent_table: basestring + :param other_table: Parent table name + :type other_table: basestring :param prefix: Optional prefix for extra table name as well as for ``other_property`` :type prefix: basestring :param dict_key: If set the value will be a dict with this key as the dict key; otherwise will @@ -290,10 +260,6 @@ def many_to_many(model_class, :param other_property: Override name of matching many-to-many property at other table; set to false to disable :type other_property: basestring|bool - :param relationship_kwargs: Extra kwargs for SQLAlchemy ``relationship`` - :type relationship_kwargs: {} - :param backref_kwargs: Extra kwargs for SQLAlchemy ``backref`` - :type backref_kwargs: {} """ this_table = model_class.__tablename__ @@ -303,69 +269,68 @@ def many_to_many(model_class, other_column_name = '{0}_id'.format(other_table) other_foreign_key = '{0}.id'.format(other_table) - secondary_table = '{0}_{1}'.format(this_table, other_table) + secondary_table_name = '{0}_{1}'.format(this_table, other_table) if prefix is not None: - secondary_table = '{0}_{1}'.format(prefix, secondary_table) + secondary_table_name = '{0}_{1}'.format(prefix, secondary_table_name) if other_property is None: other_property = '{0}_{1}'.format(prefix, this_table) - backref_kwargs = backref_kwargs or {} - backref_kwargs.setdefault('uselist', True) - - relationship_kwargs = relationship_kwargs or {} - relationship_kwargs.setdefault('secondary', _get_secondary_table( + secondary_table = _get_secondary_table( model_class.metadata, - secondary_table, + secondary_table_name, this_column_name, other_column_name, this_foreign_key, other_foreign_key - )) + ) - return _relationship(model_class, other_table, backref_kwargs, relationship_kwargs, - other_property, dict_key=dict_key) + return _relationship( + model_class, + other_table, + relationship_kwargs={'secondary': secondary_table}, + backref_kwargs={'name': other_property, 'uselist': True} if other_property else None, + dict_key=dict_key + ) -def _relationship(model_class, other_table, backref_kwargs, relationship_kwargs, other_property, - fk=None, other_fk=None, dict_key=None): +def _relationship(model_class, + other_table_name, + back_populates=None, + backref_kwargs=None, + relationship_kwargs=None, + fk=None, + other_fk=None, + dict_key=None): relationship_kwargs = relationship_kwargs or {} if fk: - relationship_kwargs.setdefault('foreign_keys', - lambda: getattr( - _get_class_for_table( - model_class, - model_class.__tablename__), - fk)) + relationship_kwargs.setdefault( + 'foreign_keys', + lambda: getattr(_get_class_for_table(model_class, model_class.__tablename__), fk) + ) elif other_fk: - relationship_kwargs.setdefault('foreign_keys', - lambda: getattr( - _get_class_for_table( - model_class, - other_table), - other_fk)) + relationship_kwargs.setdefault( + 'foreign_keys', + lambda: getattr(_get_class_for_table(model_class, other_table_name), other_fk) + ) if dict_key: relationship_kwargs.setdefault('collection_class', attribute_mapped_collection(dict_key)) - if other_property is False: - # No backref - return relationship( - lambda: _get_class_for_table(model_class, other_table), - **relationship_kwargs - ) + if backref_kwargs: + assert back_populates is None + return relationship(lambda: _get_class_for_table(model_class, other_table_name), + backref=backref(**backref_kwargs), + **relationship_kwargs + ) else: - if other_property is None: - other_property = model_class.__tablename__ - backref_kwargs = backref_kwargs or {} - return relationship( - lambda: _get_class_for_table(model_class, other_table), - backref=backref(other_property, **backref_kwargs), - **relationship_kwargs - ) + if back_populates: + relationship_kwargs['back_populates'] = back_populates + return relationship(lambda: _get_class_for_table(model_class, other_table_name), + **relationship_kwargs) def _get_class_for_table(model_class, tablename): http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/service_changes.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_changes.py b/aria/modeling/service_changes.py index a33e6ae..d81ed98 100644 --- a/aria/modeling/service_changes.py +++ b/aria/modeling/service_changes.py @@ -42,9 +42,6 @@ class ServiceUpdateBase(ModelMixin): """ Deployment update model representation. """ - - steps = None - __tablename__ = 'service_update' __private_fields__ = ['service_fk', @@ -62,11 +59,15 @@ class ServiceUpdateBase(ModelMixin): @declared_attr def execution(cls): - return relationship.many_to_one(cls, 'execution') + return relationship.one_to_one(cls, 'execution', back_populates=False) @declared_attr def service(cls): - return relationship.many_to_one(cls, 'service', parent_property='updates') + return relationship.many_to_one(cls, 'service', back_populates='updates') + + @declared_attr + def steps(cls): + return relationship.one_to_many(cls, 'service_update_step') # region foreign keys @@ -135,7 +136,7 @@ class ServiceUpdateStepBase(ModelMixin): @declared_attr def service_update(cls): - return relationship.many_to_one(cls, 'service_update', parent_property='steps') + return relationship.many_to_one(cls, 'service_update', back_populates='steps') # region foreign keys @@ -208,7 +209,7 @@ class ServiceModificationBase(ModelMixin): @declared_attr def service(cls): - return relationship.many_to_one(cls, 'service', parent_property='modifications') + return relationship.many_to_one(cls, 'service', back_populates='modifications') # region foreign keys http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/service_common.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py index d6b1f33..48c3170 100644 --- a/aria/modeling/service_common.py +++ b/aria/modeling/service_common.py @@ -275,6 +275,10 @@ class PluginSpecificationBase(TemplateModelMixin): # endregion + @declared_attr + def service_template(cls): + return relationship.many_to_one(cls, 'service_template') + @property def as_raw(self): return collections.OrderedDict(( http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/service_instance.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py index f120734..d9a8d88 100644 --- a/aria/modeling/service_instance.py +++ b/aria/modeling/service_instance.py @@ -91,6 +91,22 @@ class ServiceBase(InstanceModelMixin): # pylint: disable=too-many-public-methods 'service_template_name'] @declared_attr + def updates(cls): + return relationship.one_to_many(cls, 'service_update') + + @declared_attr + def modifications(cls): + return relationship.one_to_many(cls, 'service_modification') + + @declared_attr + def executions(cls): + return relationship.one_to_many(cls, 'execution') + + @declared_attr + def operations(cls): + return relationship.one_to_many(cls, 'operation') + + @declared_attr def service_template(cls): return relationship.many_to_one(cls, 'service_template') @@ -348,12 +364,20 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods 'service_name'] @declared_attr + def tasks(cls): + return relationship.one_to_many(cls, 'task') + + @declared_attr + def service(cls): + return relationship.many_to_one(cls, 'service') + + @declared_attr def node_template(cls): return relationship.many_to_one(cls, 'node_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -375,13 +399,13 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods @declared_attr def outbound_relationships(cls): - return relationship.one_to_many(cls, 'relationship', child_fk='source_node_fk', - child_property='source_node') + return relationship.one_to_many( + cls, 'relationship', child_fk='source_node_fk', child_property='source_node') @declared_attr def inbound_relationships(cls): - return relationship.one_to_many(cls, 'relationship', child_fk='target_node_fk', - child_property='target_node') + return relationship.one_to_many( + cls, 'relationship', child_fk='target_node_fk', child_property='target_node') @declared_attr def host(cls): @@ -432,7 +456,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods @declared_attr def node_template_fk(cls): """For Node many-to-one to NodeTemplate""" - return relationship.foreign_key('node_template', nullable=True) + return relationship.foreign_key('node_template') # endregion @@ -469,7 +493,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods from . import models context = ConsumptionContext.get_thread_local() # Find target nodes - target_nodes = target_node_template.nodes.all() + target_nodes = target_node_template.nodes if target_nodes: target_node = None target_capability = None @@ -577,6 +601,7 @@ class NodeBase(InstanceModelMixin): # pylint: disable=too-many-public-methods utils.dump_dict_values(self.capabilities, 'Capabilities') utils.dump_list_values(self.outbound_relationships, 'Relationships') + class GroupBase(InstanceModelMixin): """ Usually an instance of a :class:`GroupTemplate`. @@ -609,12 +634,16 @@ class GroupBase(InstanceModelMixin): 'group_template_fk'] @declared_attr + def service(cls): + return relationship.many_to_one(cls, 'service') + + @declared_attr def group_template(cls): return relationship.many_to_one(cls, 'group_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -708,12 +737,16 @@ class PolicyBase(InstanceModelMixin): 'policy_template_fk'] @declared_attr + def service(cls): + return relationship.many_to_one(cls, 'service') + + @declared_attr def policy_template(cls): return relationship.many_to_one(cls, 'policy_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -802,12 +835,16 @@ class SubstitutionBase(InstanceModelMixin): 'substitution_template_fk'] @declared_attr + def service(cls): + return relationship.one_to_one(cls, 'service') + + @declared_attr def substitution_template(cls): return relationship.many_to_one(cls, 'substitution_template') @declared_attr def node_type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) @declared_attr def mappings(cls): @@ -876,6 +913,10 @@ class SubstitutionMappingBase(InstanceModelMixin): 'requirement_template_fk'] @declared_attr + def substitution(cls): + return relationship.many_to_one(cls, 'substitution', back_populates='mappings') + + @declared_attr def node(cls): return relationship.one_to_one(cls, 'node') @@ -984,6 +1025,20 @@ class RelationshipBase(InstanceModelMixin): 'target_node_name'] @declared_attr + def tasks(cls): + return relationship.one_to_many(cls, 'task') + + @declared_attr + def source_node(cls): + return relationship.many_to_one( + cls, 'node', fk='source_node_fk', back_populates='outbound_relationships') + + @declared_attr + def target_node(cls): + return relationship.many_to_one( + cls, 'node', fk='target_node_fk', back_populates='inbound_relationships') + + @declared_attr def relationship_template(cls): return relationship.many_to_one(cls, 'relationship_template') @@ -993,7 +1048,7 @@ class RelationshipBase(InstanceModelMixin): @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) @declared_attr def target_capability(cls): @@ -1138,12 +1193,16 @@ class CapabilityBase(InstanceModelMixin): 'capability_template_fk'] @declared_attr + def node(cls): + return relationship.many_to_one(cls, 'node') + + @declared_attr def capability_template(cls): return relationship.many_to_one(cls, 'capability_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) min_occurrences = Column(Integer, default=None) max_occurrences = Column(Integer, default=None) @@ -1248,12 +1307,24 @@ class InterfaceBase(InstanceModelMixin): 'interface_template_fk'] @declared_attr + def node(cls): + return relationship.many_to_one(cls, 'node') + + @declared_attr + def relationship(cls): + return relationship.many_to_one(cls, 'relationship') + + @declared_attr + def group(cls): + return relationship.many_to_one(cls, 'group') + + @declared_attr def interface_template(cls): return relationship.many_to_one(cls, 'interface_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -1363,6 +1434,14 @@ class OperationBase(InstanceModelMixin): 'operation_template_fk'] @declared_attr + def service(cls): + return relationship.many_to_one(cls, 'service') + + @declared_attr + def interface(cls): + return relationship.many_to_one(cls, 'interface') + + @declared_attr def operation_template(cls): return relationship.many_to_one(cls, 'operation_template') @@ -1485,12 +1564,16 @@ class ArtifactBase(InstanceModelMixin): 'artifact_template_fk'] @declared_attr + def node(cls): + return relationship.many_to_one(cls, 'node') + + @declared_attr def artifact_template(cls): return relationship.many_to_one(cls, 'artifact_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) source_path = Column(Text) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/aria/modeling/service_template.py ---------------------------------------------------------------------- diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py index 7246ff1..f3af0d2 100644 --- a/aria/modeling/service_template.py +++ b/aria/modeling/service_template.py @@ -110,11 +110,19 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public main_file_name = Column(Text) @declared_attr + def services(cls): + return relationship.one_to_many(cls, 'service') + + @declared_attr def meta_data(cls): # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy! return relationship.many_to_many(cls, 'metadata', dict_key='name') @declared_attr + def operation_templates(cls): + return relationship.one_to_many(cls, 'operation_template') + + @declared_attr def node_templates(cls): return relationship.one_to_many(cls, 'node_template', dict_key='name') @@ -148,32 +156,31 @@ class ServiceTemplateBase(TemplateModelMixin): # pylint: disable=too-many-public @declared_attr def node_types(cls): - return relationship.one_to_one(cls, 'type', fk='node_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='node_type_fk', back_populates=False) @declared_attr def group_types(cls): - return relationship.one_to_one(cls, 'type', fk='group_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='group_type_fk', back_populates=False) @declared_attr def policy_types(cls): - return relationship.one_to_one(cls, 'type', fk='policy_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='policy_type_fk', back_populates=False) @declared_attr def relationship_types(cls): - return relationship.one_to_one(cls, 'type', fk='relationship_type_fk', - other_property=False) + return relationship.one_to_one(cls, 'type', fk='relationship_type_fk', back_populates=False) @declared_attr def capability_types(cls): - return relationship.one_to_one(cls, 'type', fk='capability_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='capability_type_fk', back_populates=False) @declared_attr def interface_types(cls): - return relationship.one_to_one(cls, 'type', fk='interface_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='interface_type_fk', back_populates=False) @declared_attr def artifact_types(cls): - return relationship.one_to_one(cls, 'type', fk='artifact_type_fk', other_property=False) + return relationship.one_to_one(cls, 'type', fk='artifact_type_fk', back_populates=False) # region orchestration @@ -415,7 +422,7 @@ class NodeTemplateBase(TemplateModelMixin): @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) default_instances = Column(Integer, default=1) @@ -423,6 +430,14 @@ class NodeTemplateBase(TemplateModelMixin): max_instances = Column(Integer, default=None) @declared_attr + def nodes(cls): + return relationship.one_to_many(cls, 'node') + + @declared_attr + def service_template(cls): + return relationship.many_to_one(cls, 'service_template') + + @declared_attr def properties(cls): return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name') @@ -440,8 +455,7 @@ class NodeTemplateBase(TemplateModelMixin): @declared_attr def requirement_templates(cls): - return relationship.one_to_many(cls, 'requirement_template', child_fk='node_template_fk', - child_property='node_template') + return relationship.one_to_many(cls, 'requirement_template', child_fk='node_template_fk') target_node_template_constraints = Column(modeling_types.StrictList(FunctionType)) @@ -572,8 +586,16 @@ class GroupTemplateBase(TemplateModelMixin): 'service_template_fk'] @declared_attr + def groups(cls): + return relationship.one_to_many(cls, 'group') + + @declared_attr + def service_template(cls): + return relationship.many_to_one(cls, 'service_template') + + @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -622,7 +644,7 @@ class GroupTemplateBase(TemplateModelMixin): utils.instantiate_dict(self, group.interfaces, self.interface_templates) if self.node_templates: for node_template in self.node_templates: - group.nodes += node_template.nodes.all() + group.nodes += node_template.nodes return group def validate(self): @@ -673,12 +695,19 @@ class PolicyTemplateBase(TemplateModelMixin): __tablename__ = 'policy_template' - __private_fields__ = ['type_fk', - 'service_template_fk'] + __private_fields__ = ['type_fk', 'service_template_fk'] + + @declared_attr + def policies(cls): + return relationship.one_to_many(cls, 'policy') + + @declared_attr + def service_template(cls): + return relationship.many_to_one(cls, 'service_template') @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -725,10 +754,10 @@ class PolicyTemplateBase(TemplateModelMixin): utils.instantiate_dict(self, policy.properties, self.properties) if self.node_templates: for node_template in self.node_templates: - policy.nodes += node_template.nodes.all() + policy.nodes += node_template.nodes if self.group_templates: for group_template in self.group_templates: - policy.groups += group_template.groups.all() + policy.groups += group_template.groups return policy def validate(self): @@ -773,8 +802,12 @@ class SubstitutionTemplateBase(TemplateModelMixin): __private_fields__ = ['node_type_fk'] @declared_attr + def substitutions(cls): + return relationship.one_to_many(cls, 'substitution') + + @declared_attr def node_type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) @declared_attr def mappings(cls): @@ -843,6 +876,10 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin): 'requirement_template_fk'] @declared_attr + def substitution_template(cls): + return relationship.many_to_one(cls, 'substitution_template', back_populates='mappings') + + @declared_attr def node_template(cls): return relationship.one_to_one(cls, 'node_template') @@ -889,7 +926,7 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin): def instantiate(self, container): from . import models context = ConsumptionContext.get_thread_local() - nodes = self.node_template.nodes.all() + nodes = self.node_template.nodes if len(nodes) == 0: context.validation.report( 'mapping "{0}" refers to node template "{1}" but there are no ' @@ -968,19 +1005,27 @@ class RequirementTemplateBase(TemplateModelMixin): 'relationship_template_fk'] @declared_attr + def relationships(cls): + return relationship.one_to_many(cls, 'relationship') + + @declared_attr + def node_template(cls): + return relationship.many_to_one(cls, 'node_template', fk='node_template_fk') + + @declared_attr def target_node_type(cls): - return relationship.many_to_one(cls, 'type', fk='target_node_type_fk', - parent_property=False) + return relationship.many_to_one( + cls, 'type', fk='target_node_type_fk', back_populates=False) @declared_attr def target_node_template(cls): - return relationship.one_to_one(cls, 'node_template', fk='target_node_template_fk', - other_property=False) + return relationship.one_to_one( + cls, 'node_template', fk='target_node_template_fk', back_populates=False) @declared_attr def target_capability_type(cls): return relationship.one_to_one(cls, 'type', fk='target_capability_type_fk', - other_property=False) + back_populates=False) target_capability_name = Column(Text) target_node_template_constraints = Column(modeling_types.StrictList(FunctionType)) @@ -1149,8 +1194,12 @@ class RelationshipTemplateBase(TemplateModelMixin): __private_fields__ = ['type_fk'] @declared_attr + def relationships(cls): + return relationship.one_to_many(cls, 'relationship') + + @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -1246,8 +1295,16 @@ class CapabilityTemplateBase(TemplateModelMixin): 'node_template_fk'] @declared_attr + def capabilities(cls): + return relationship.one_to_many(cls, 'capability') + + @declared_attr + def node_template(cls): + return relationship.many_to_one(cls, 'node_template') + + @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) min_occurrences = Column(Integer, default=None) # optional @@ -1379,8 +1436,24 @@ class InterfaceTemplateBase(TemplateModelMixin): 'relationship_template_fk'] @declared_attr + def interfaces(cls): + return relationship.one_to_many(cls, 'interface') + + @declared_attr + def relationship_template(cls): + return relationship.many_to_one(cls, 'relationship_template') + + @declared_attr + def group_template(cls): + return relationship.many_to_one(cls, 'group_template') + + @declared_attr + def node_template(cls): + return relationship.many_to_one(cls, 'node_template') + + @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) @@ -1497,6 +1570,18 @@ class OperationTemplateBase(TemplateModelMixin): description = Column(Text) @declared_attr + def operations(cls): + return relationship.one_to_many(cls, 'operation') + + @declared_attr + def service_template(cls): + return relationship.many_to_one(cls, 'service_template') + + @declared_attr + def interface_template(cls): + return relationship.many_to_one(cls, 'interface_template') + + @declared_attr def plugin_specification(cls): return relationship.one_to_one(cls, 'plugin_specification') @@ -1617,8 +1702,16 @@ class ArtifactTemplateBase(TemplateModelMixin): 'node_template_fk'] @declared_attr + def artifacts(cls): + return relationship.one_to_many(cls, 'artifact') + + @declared_attr + def node_template(cls): + return relationship.many_to_one(cls, 'node_template') + + @declared_attr def type(cls): - return relationship.many_to_one(cls, 'type') + return relationship.many_to_one(cls, 'type', back_populates=False) description = Column(Text) source_path = Column(Text) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/tests/orchestrator/context/test_operation.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py index 6721b29..f55b83e 100644 --- a/tests/orchestrator/context/test_operation.py +++ b/tests/orchestrator/context/test_operation.py @@ -353,10 +353,10 @@ def _assert_loggins(ctx, inputs): tasks = ctx.model.task.list() assert len(tasks) == 1 task = tasks[0] - assert task.logs.count() == 4 + assert len(task.logs) == 4 logs = ctx.model.log.list() - assert len(logs) == execution.logs.count() == 6 + assert len(logs) == len(execution.logs) == 6 assert set(logs) == set(execution.logs) assert all(l.execution == execution for l in logs) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f86477e1/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml ---------------------------------------------------------------------- diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml index b950fa4..3b4f371 100644 --- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml +++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml @@ -33,7 +33,6 @@ imports: - types/mongodb.yaml - types/nginx.yaml - aria-1.0 - dsl_definitions: default_openstack_credential: &DEFAULT_OPENSTACK_CREDENTIAL
