NOTICE

The upcoming release of Featuretools 1.0.0 contains several breaking changes. Users are encouraged to test this version prior to release by installing from GitHub:

pip install https://github.com/alteryx/featuretools/archive/woodwork-integration.zip

For details on migrating to the new version, refer to Transitioning to Featuretools Version 1.0. Please report any issues in the Featuretools GitHub repo or by messaging in Alteryx Open Source Slack.


Source code for featuretools.entityset.relationship

[docs]class Relationship(object): """Class to represent an relationship between entities See Also: :class:`.EntitySet`, :class:`.Entity`, :class:`.Variable` """
[docs] def __init__(self, parent_variable, child_variable): """ Create a relationship Args: parent_variable (:class:`.Discrete`): Instance of variable in parent entity. Must be a Discrete Variable child_variable (:class:`.Discrete`): Instance of variable in child entity. Must be a Discrete Variable """ self.entityset = child_variable.entityset self._parent_entity_id = parent_variable.entity.id self._child_entity_id = child_variable.entity.id self._parent_variable_id = parent_variable.id self._child_variable_id = child_variable.id if (parent_variable.entity.index is not None and parent_variable.id != parent_variable.entity.index): raise AttributeError("Parent variable '%s' is not the index of entity %s" % (parent_variable, parent_variable.entity))
@classmethod def from_dictionary(cls, arguments, es): parent_entity = es[arguments['parent_entity_id']] child_entity = es[arguments['child_entity_id']] parent_variable = parent_entity[arguments['parent_variable_id']] child_variable = child_entity[arguments['child_variable_id']] return cls(parent_variable, child_variable) def __repr__(self): ret = u"<Relationship: %s.%s -> %s.%s>" % \ (self._child_entity_id, self._child_variable_id, self._parent_entity_id, self._parent_variable_id) return ret def __eq__(self, other): if not isinstance(other, self.__class__): return False return self._parent_entity_id == other._parent_entity_id and \ self._child_entity_id == other._child_entity_id and \ self._parent_variable_id == other._parent_variable_id and \ self._child_variable_id == other._child_variable_id def __hash__(self): return hash((self._parent_entity_id, self._child_entity_id, self._parent_variable_id, self._child_variable_id)) @property def parent_entity(self): """Parent entity object""" return self.entityset[self._parent_entity_id] @property def child_entity(self): """Child entity object""" return self.entityset[self._child_entity_id] @property def parent_variable(self): """Instance of variable in parent entity""" return self.parent_entity[self._parent_variable_id] @property def child_variable(self): """Instance of variable in child entity""" return self.child_entity[self._child_variable_id] @property def parent_name(self): """The name of the parent, relative to the child.""" if self._is_unique(): return self._parent_entity_id else: return '%s[%s]' % (self._parent_entity_id, self._child_variable_id) @property def child_name(self): """The name of the child, relative to the parent.""" if self._is_unique(): return self._child_entity_id else: return '%s[%s]' % (self._child_entity_id, self._child_variable_id) def to_dictionary(self): return { 'parent_entity_id': self._parent_entity_id, 'child_entity_id': self._child_entity_id, 'parent_variable_id': self._parent_variable_id, 'child_variable_id': self._child_variable_id, } def _is_unique(self): """Is there any other relationship with same parent and child entities?""" es = self.child_entity.entityset relationships = es.get_forward_relationships(self._child_entity_id) n = len([r for r in relationships if r._parent_entity_id == self._parent_entity_id]) assert n > 0, 'This relationship is missing from the entityset' return n == 1
class RelationshipPath(object): def __init__(self, relationships_with_direction): self._relationships_with_direction = relationships_with_direction @property def name(self): relationship_names = [_direction_name(is_forward, r) for is_forward, r in self._relationships_with_direction] return '.'.join(relationship_names) def entities(self): if self: # Yield first entity. is_forward, relationship = self[0] if is_forward: yield relationship.child_entity.id else: yield relationship.parent_entity.id # Yield the entity pointed to by each relationship. for is_forward, relationship in self: if is_forward: yield relationship.parent_entity.id else: yield relationship.child_entity.id def __add__(self, other): return RelationshipPath(self._relationships_with_direction + other._relationships_with_direction) def __getitem__(self, index): return self._relationships_with_direction[index] def __iter__(self): for is_forward, relationship in self._relationships_with_direction: yield is_forward, relationship def __len__(self): return len(self._relationships_with_direction) def __eq__(self, other): return isinstance(other, RelationshipPath) and \ self._relationships_with_direction == other._relationships_with_direction def __ne__(self, other): return not self == other def __repr__(self): if self._relationships_with_direction: path = '%s.%s' % (next(self.entities()), self.name) else: path = '[]' return '<RelationshipPath %s>' % path def _direction_name(is_forward, relationship): if is_forward: return relationship.parent_name else: return relationship.child_name