Beispiel #1
0
 def test_list_data(self, rel_data_lists, rel_type, rel_keys):
     q, p = unwind_create_relationships_query(rel_data_lists, rel_type, keys=rel_keys)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a) WHERE id(a) = r[0]\n"
                  "MATCH (b) WHERE id(b) = r[2]\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ += {`employee id`: r[1][0], `job title`: r[1][1], since: r[1][2]}")
     assert p == {"data": rel_data_lists}
Beispiel #2
0
 def test_dict_data(self, rel_data_dicts, rel_type):
     q, p = unwind_create_relationships_query(rel_data_dicts, rel_type)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a) WHERE id(a) = r[0]\n"
                  "MATCH (b) WHERE id(b) = r[2]\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ += r[1]")
     assert p == {"data": rel_data_dicts}
Beispiel #3
0
 def test_with_end_node_key(self, rel_data_dicts, rel_type, end_node_key):
     q, p = unwind_create_relationships_query(rel_data_dicts, rel_type,
                                              end_node_key=end_node_key)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a) WHERE id(a) = r[0]\n"
                  "MATCH (b:Company {name:r[2]})\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ += r[1]")
     assert p == {"data": rel_data_dicts}
Beispiel #4
0
 def test_with_start_node_no_keys(self, rel_data_lists_no_key, rel_type, rel_keys,
                                  start_node_key):
     q, p = unwind_create_relationships_query(rel_data_lists_no_key, rel_type,
                                              start_node_key=start_node_key,
                                              end_node_key="Company", keys=rel_keys)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a:Person {name:r[0]})\n"
                  "MATCH (b:Company)\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ += {`employee id`: r[1][0], `job title`: r[1][1], since: r[1][2]}")
     assert p == {"data": rel_data_lists_no_key}
Beispiel #5
0
 def test_with_start_node_double_key(self, rel_data_lists_double_key, rel_keys,
                                     rel_type, start_node_double_key):
     q, p = unwind_create_relationships_query(rel_data_lists_double_key, rel_type,
                                              start_node_key=start_node_double_key,
                                              keys=rel_keys)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a:Person {name:r[0][0], `family name`:r[0][1]})\n"
                  "MATCH (b) WHERE id(b) = r[2]\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ += {`employee id`: r[1][0], `job title`: r[1][1], since: r[1][2]}")
     assert p == {"data": rel_data_lists_double_key}
Beispiel #6
0
 def test_with_start_node_key(self, rel_data_dicts, rel_type,
                              start_node_key):
     q, p = unwind_create_relationships_query(rel_data_dicts,
                                              rel_type,
                                              start_node_key=start_node_key)
     assert q == ("UNWIND $data AS r\n"
                  "MATCH (a:Person {name:r[0]})\n"
                  "MATCH (b) WHERE id(b) = r[2]\n"
                  "CREATE (a)-[_:WORKS_FOR]->(b)\n"
                  "SET _ = r[1]")
     assert p == {"data": rel_data_dicts}
Beispiel #7
0
def merge_relationships(tx,
                        data,
                        merge_key,
                        keys=None,
                        start_node_key=None,
                        end_node_key=None):
    """ Merge relationships from an iterable sequence of raw
    relationship data.

    :param tx: :class:`.Transaction` in which to carry out this
        operation
    :param data:
    :param merge_key:
    :param keys:
    :param start_node_key:
    :param end_node_key:
    :return:
    """
    list(
        tx.run(*unwind_create_relationships_query(
            data, merge_key, keys, start_node_key, end_node_key)))
Beispiel #8
0
def create_relationships(tx,
                         data,
                         rel_type,
                         start_node_key=None,
                         end_node_key=None,
                         keys=None):
    """ Create relationships from an iterable sequence of raw
    relationship data.

    The raw relationship `data` is supplied as a list of triples (or
    3-item lists), each representing (start_node, detail, end_node).
    The `rel_type` specifies the type of relationship to create, and is
    fixed for the entire data set.

    Start and end node information can either be provided as an
    internal node ID or, in conjunction with a `start_node_key` or
    `end_node_key`, a tuple or list of property values to ``MATCH``.
    For example, to link people to their place of work, the code below
    could be used:

        >>> from py2neo import Graph
        >>> from py2neo.bulk import create_relationships
        >>> g = Graph()
        >>> data = [
            (("Alice", "Smith"), {"since": 1999}, "ACME"),
            (("Bob", "Jones"), {"since": 2002}, "Bob Corp"),
            (("Carol", "Singer"), {"since": 1981}, "The Daily Planet"),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR", \\
            start_node_key=("Person", "name", "family name"), end_node_key=("Company", "name"))

    If the company node IDs were already known by other means, the code
    could instead look like this:

        >>> data = [
            (("Alice", "Smith"), {"since": 1999}, 123),
            (("Bob", "Jones"), {"since": 2002}, 124),
            (("Carol", "Singer"), {"since": 1981}, 201),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR", \\
            start_node_key=("Person", "name", "family name"))

    These `start_node_key` and `end_node_key` arguments are interpreted
    in a similar way to the `merge_key` of :func:`merge_nodes`, except
    that the values are instead used to construct ``MATCH`` patterns.
    Additionally, passing :py:const:`None` indicates that a match by
    node ID should be used. The table below shows example combinations,
    where ``x`` is the input value drawn from the source data.

    .. table::
        :widths: 40 60

        =================================================  ===========================================================
        Argument                                           ``MATCH`` Clause
        =================================================  ===========================================================
        :py:const:`None`                                   ``MATCH (a) WHERE id(a) = x``
        ``("Person", "name")``                             ``MATCH (a:Person {name:x})``
        ``("Person", "name", "family name")``              ``MATCH (a:Person {name:x[0], `family name`:x[1]})``
        ``(("Person", "Female"), "name")``                 ``MATCH (a:Female:Person {name:x})``
        ``(("Person", "Female"), "name", "family name")``  ``MATCH (a:Female:Person {name:x[0], `family name`:x[1]})``
        =================================================  ===========================================================


    As with other methods, such as :func:`.create_nodes`, the
    relationship `data` can also be supplied as a list of property
    values, indexed by `keys`. This can avoid sending duplicated key
    names over the network, and alters the method call as follows:

        >>> data = [
            (("Alice", "Smith"), [1999], 123),
            (("Bob", "Jones"), [2002], 124),
            (("Carol", "Singer"), [1981], 201),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR" \\
            start_node_key=("Person", "name", "family name")), keys=["since"])

    :param tx: :class:`.Transaction` in which to carry out this
        operation
    :param data: relationship data supplied as a list of triples of
        `(start_node, detail, end_node)`
    :param rel_type: relationship type name to create
    :param start_node_key: optional tuple of (label, key1, key2...) on
        which to match relationship start nodes, matching by node ID
        if not provided
    :param end_node_key: optional tuple of (label, key1, key2...) on
        which to match relationship end nodes, matching by node ID
        if not provided
    :param keys: optional set of field names for the relationship
        `detail` (if supplied as value lists)
    :return:
    """
    list(
        tx.run(*unwind_create_relationships_query(
            data, rel_type, start_node_key, end_node_key, keys)))
Beispiel #9
0
def create_relationships(tx,
                         data,
                         rel_type,
                         keys=None,
                         start_node_key=None,
                         end_node_key=None):
    """ Create relationships from an iterable sequence of raw
    relationship data.

    The raw relationship `data` is supplied as a list of triples (or
    3-item lists), each representing (start_node, detail, end_node).
    The `rel_type` specifies the type of relationship to create, and is
    fixed for the entire data set.

    Start and end node information can either be provided as an
    internal node ID or, in conjunction with a `start_node_key` or
    `end_node_key`, a tuple or list of property values to ``MATCH``.
    For example, to link people to their place of work, the code below
    could be used:

        >>> from py2neo import Graph
        >>> from py2neo.data.operations import create_relationships
        >>> g = Graph()
        >>> data = [
            (("Alice", "Smith"), {"since": 1999}, "ACME"),
            (("Bob", "Jones"), {"since": 2002}, "Bob Corp"),
            (("Carol", "Singer"), {"since": 1981}, "The Daily Planet"),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR", \
            start_node_key=("Person", "name", "family name"), \
            end_node_key=("Company", "name"))

    If the company node IDs were already known, the code could instead
    look like this:

        >>> data = [
            (("Alice", "Smith"), {"since": 1999}, 123),
            (("Bob", "Jones"), {"since": 2002}, 124),
            (("Carol", "Singer"), {"since": 1981}, 201),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR", \
            start_node_key=("Person", "name", "family name"))

    As with other methods, such as :meth:`.create_nodes`, the
    relationship `data` can also be supplied as a list of property
    values, indexed by `keys`. This can avoid sending duplicated key
    names over the network, and alters the method call as follows:

        >>> data = [
            (("Alice", "Smith"), [1999], 123),
            (("Bob", "Jones"), [2002], 124),
            (("Carol", "Singer"), [1981], 201),
        ]
        >>> create_relationships(g.auto(), data, "WORKS_FOR", keys=["since"] \
            start_node_key=("Person", "name", "family name"))

    :param tx: :class:`.Transaction` in which to carry out this
        operation
    :param data:
    :param rel_type:
    :param keys:
    :param start_node_key:
    :param end_node_key:
    :return:
    """
    list(
        tx.run(*unwind_create_relationships_query(
            data, rel_type, keys, start_node_key, end_node_key)))