pythonneo4jpy2neo

Updating a node with merge using Py2Neo


I'm trying to merge and then update a graph using the py2neo library. My code looks roughly like

from py2neo import Graph, Node, Relationship

graph = Graph(host, auth=(user, password,))

tx = graph.begin()
alice = Node("Person", name="Alice")
bob = Node("Person", name="Bob")
KNOWS = Relationship(alice, "KNOWS", bob)
tx.create(KNOWS)
graph.commit(tx)

This creates the nodes and edges as expected as

(:Person {name: "Alice"})-[:KNOWS]->(:Person {name: "Bob"})

If I try to modify alice in a new transaction though, I get no change

e.g.

new_tx = graph.begin()
alice["age"] = 32
new_tx.merge(alice, "Person", "name")
graph.commit(new_tx)

I suspect I have misunderstood how the Transaction works here. I would expect the above to be equivalent to either finding Alice and updating with the new property or creating a new node.

Update: I have discovered the Graph.push method, but would still appreciate advice on best practice.


Solution

  • You need to define a primary key to let the MERGE know which property to use as a primary key. From the documentation:

    The primary property key used for Cypher MATCH and MERGE operations. If undefined, the special value of "id" is used to hinge uniqueness on the internal node ID instead of a property. Note that this alters the behaviour of operations such as Graph.create() and Graph.merge() on GraphObject instances.

    It's probably best practice to define a custom class for every node type and define the primary key there.

    class Person(GraphObject):
        __primarykey__ = "name"
    
        name = Property()
        born = Property()
    
        acted_in = RelatedTo(Movie)
        directed = RelatedTo(Movie)
        produced = RelatedTo(Movie)