diff --git a/hshetl/entities.py b/hshetl/entities.py index ba3a422d70452bebb34c05c10b5a95fc6d3a67c1..59f174e79b39227a74f2907c00e861d2f9771ec1 100644 --- a/hshetl/entities.py +++ b/hshetl/entities.py @@ -521,6 +521,7 @@ class Result(object): '''Initializes the necessary properties.''' self.entity = entity self.source = NameResolver(self.entity, 'source', source)() + '''source is a Result, NOT a container''' self.update = EntityList(self.source) self.insert = EntityList(self.source) @@ -571,7 +572,7 @@ class EntityList(list): ''' def __init__(self, result): - '''Default constructor''' + '''Expects a Result instance''' self.result = result self.source = result.source_container self.target = result.target_container diff --git a/hshetl/transformers.py b/hshetl/transformers.py index c7bd578d23e0e30b4cb667f6b93485dfda76dee4..bdd7b5c6c26bedfe2165a3f3d5198f0764444767 100644 --- a/hshetl/transformers.py +++ b/hshetl/transformers.py @@ -291,3 +291,68 @@ class PropertiesTransformer(AbstractTransformer): transformed_properties[prop] = eval('pt.{}.value'.format(operation), globals(), dict(properties.items() + locals().items())) return transformed_properties + +@yamlify +class UuidTransformer(AbstractTransformer): + '''Creates an uuid for entity. + + Applies all operations to the fields in the new data container. + + .. function:: __init__(source[, *args[, **kwargs]]) + + Constructor + + :param source: The source container. + :param **kwargs: Accepts parameters from :class:`.AbstractTransformer`. + :type source: string + + A loader inside of a YAML job definition with more parameters: + + .. code-block:: yaml + + transformer: !uuid + entity: !entity + id: string + source: foobar + + ''' + + yaml_tag = u'!uuid' + + def __init__(self, source, uuid_attribute, mapping = {}, *args, **kwargs): + super(UuidTransformer, self).__init__(*args, **kwargs) + self.source = source + self.uuid_attr = uuid_attribute + self.mapping = mapping + '''The source container to work on.''' + if self.entity is not None: + self.source = NameResolver(self.entity, 'source', source)() + + def create_container(self): + if isinstance(self.source, str) and self.entity is not None: + self.source = NameResolver(self.entity, 'source', self.source)() + else: + raise Exception("Source is of type string and entity is None, so the NameResolver cannot find a correspinding container.") + if self.mapping is not {}: + mapped_identifiers = [x if x not in self.mapping.keys() else self.mapping[x] for x in self.source.identifiers] + self.result = Container(name = self.name, + identifiers = mapped_identifiers, + properties = self.entity.properties) + self.entity.add(self.result) + + def can_execute(self): + '''Whether the Transformer has everything set needed for its transform operation.''' + return self.entity is not None and self.source is not None + + def _execute(self): + for record in self.entity.record_repository.itervalues(): + identifier = record.get_container_identifier(self.source) + if identifier is None: continue # ignore records not known by source. + transformed = self._execute_operations(record) + record.load(identifier, transformed, self.result) + + def _execute_operations(self, record): + properties = record.get_properties(self.source) + transformed_properties = properties.copy() + transformed_properties[self.uuid_attr] = uuid().hex + return transformed_properties \ No newline at end of file