Ejemplo n.º 1
0
def get_message_id(manager, obj):
    unique_attrs = set()
    for cls, attr_name in manager.type_registry.get_unique_attrs(type(obj)):
        value = getattr(obj, attr_name)
        if value is not None:
            unique_attrs.add((
                get_type_id(cls).lower(),  # backwards compat; was index name
                attr_name,
                object_to_db_value(value),
            ))

    return json.dumps(sorted(unique_attrs))
Ejemplo n.º 2
0
    def get_by_unique_attr(self, cls, attr_name, values):
        """Bulk load entities from a list of values for a unique attribute

        Returns:
            A generator (obj1, obj2, ...) corresponding to the `values` list

        If any values are missing in the index, the corresponding obj is None
        """
        if not hasattr(cls, attr_name):
            raise ValueError("{} has no attribute {}".format(cls, attr_name))

        registry = self.type_registry
        for declaring_cls, attr in registry.get_unique_attrs(cls):
            if attr == attr_name:
                break
        else:
            raise ValueError("{}.{} is not unique".format(cls, attr_name))

        type_id = get_type_id(cls)
        query = "MATCH (n:%(label)s {%(attr)s: {id}}) RETURN n" % {
            'label': type_id,
            'attr': attr_name,
        }
        batch = neo4j.ReadBatch(self._conn)
        for value in values:
            db_value = object_to_db_value(value)
            batch.append_cypher(query, params={'id': db_value})

        # When upgrading to py2neo 1.6, consider changing this to batch.stream
        batch_result = batch.submit()

        # `batch_result` is a list of either one element lists (for matches)
        # or empty lists. Unpack to flatten (and hydrate to Kaiso objects)
        result = (self._convert_value(row) for row in batch_result)

        return result
Ejemplo n.º 3
0
def get_match_clause(obj, name, type_registry):
    """Return node lookup by index for a match clause using unique attributes

    Args:
        obj: An object to create an index lookup.
        name: The name of the object in the query.
    Returns:
        A string with an index lookup for a cypher MATCH clause
    """

    if isinstance(obj, PersistableType):
        value = get_type_id(obj)
        return '({name}:PersistableType {{id: {value}}})'.format(
            name=name,
            value=json.dumps(object_to_db_value(value)),
        )

    if isinstance(obj, Relationship):
        if obj.start is None or obj.end is None:
            raise NoUniqueAttributeError(
                "{} is missing a start or end node".format(obj)
            )
        neo4j_rel_name = get_neo4j_relationship_name(type(obj))
        start_name = '{}__start'.format(name)
        end_name = '{}__end'.format(name)
        query = """
            {start_clause},
            {end_clause},
            ({start_name})-[{name}:{neo4j_rel_name}]->({end_name})
        """.format(
            name=name,
            start_clause=get_match_clause(
                obj.start, start_name, type_registry,
            ),
            end_clause=get_match_clause(
                obj.end, end_name, type_registry,
            ),
            start_name=start_name,
            end_name=end_name,
            neo4j_rel_name=neo4j_rel_name,
        )
        return dedent(query)

    match_params = {}
    label_classes = set()
    for cls, attr_name in type_registry.get_unique_attrs(type(obj)):
        value = getattr(obj, attr_name)
        if value is not None:
            label_classes.add(cls)
            match_params[attr_name] = value
    if not match_params:
        raise NoUniqueAttributeError(
            "{} doesn't have any unique attributes".format(obj)
        )
    match_params_string = inline_parameter_map(
        dict_to_db_values_dict(match_params)
    )
    labels = ':'.join(get_type_id(cls) for cls in label_classes)

    return '({name}:{labels} {match_params_string})'.format(
        name=name,
        labels=labels,
        attr_name=attr_name,
        match_params_string=match_params_string,
    )