Пример #1
0
    def get_related_objects(self, rel_cls, ref_cls, obj):

        if ref_cls is Outgoing:
            rel_query = '(n)-[relation:{}]->(related)'
        elif ref_cls is Incoming:
            rel_query = '(n)<-[relation:{}]-(related)'

        # TODO: should get the rel name from descriptor?
        rel_query = rel_query.format(get_neo4j_relationship_name(rel_cls))

        query = join_lines(
            'MATCH {idx_lookup}, {rel_query}'
            'RETURN related, relation'
        )

        query = query.format(
            idx_lookup=get_match_clause(obj, 'n', self.type_registry),
            rel_query=rel_query
        )

        return self.query(query)
Пример #2
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,
    )