Kevin Paul Babu
Kevin Paul Babu

Reputation: 13

How to update the existing nodes in neo4j using python

I've successfully managed to display and create nodes in Neo4j using Python, but I'm struggling to update nodes in Neo4j using Python. I've attempted to seek assistance from ChatGPT, but I'm still unable to figure out how to update nodes in Neo4j This is the python code

from neo4j import GraphDatabase


class Neo4jConnector:
    def __init__(self, uri, user, password):
        self._driver = GraphDatabase.driver(uri, auth=(user, password))

    def close(self):
        self._driver.close()

    @property
    def driver(self):
        return self._driver


def create_node(neo4j_conn, sender, receiver, message, profile_id, rule_type, processing_flag, return_name):
    query = (
        "CREATE (n:Message {sender: $sender, receiver: $receiver, "
        "message: $message, profile_id: $profile_id, rule_type: $rule_type, "
        "processing_flag: $processing_flag,return_name:$return_name})"
    )

    with neo4j_conn._driver.session() as session:
        session.write_transaction(lambda tx: tx.run(query, sender=sender, receiver=receiver,
                                                    message=message, profile_id=profile_id,
                                                    rule_type=rule_type, processing_flag=processing_flag,
                                                    return_name=return_name))


def display_nodes(neo4j_conn):
    query = "MATCH (n:Message) RETURN n"

    with neo4j_conn._driver.session() as session:
        result = session.run(query)
        for record in result:
            node = record["n"]
            print(node)


def get_nodes_by_processing_flag(tx, processing_flag):
    query = (
        "MATCH (node:Message) "
        "WHERE node.processing_flag = $processing_flag "
        "RETURN node"
    )
    result = []
    for record in tx.run(query, processing_flag=processing_flag):
        result.append(record["node"])
    return result


def update_node(tx, new_profile_id, new_message, new_processing_flag, return_name):
    query = (
        "MATCH (n) WHERE return_name(n) = $return_name"
        "SET n.profile_id = $new_profile_id, "
        "    n.message = $new_message, "
        "    n.processing_flag = $new_processing_flag "
    )
    tx.run(query,  new_profile_id=new_profile_id, new_message=new_message,
           new_processing_flag=new_processing_flag, return_name=return_name)


def main():
    uri = "bolt://localhost:7687"  # Update with your Neo4j server URI
    user = "admin"  # Update with your Neo4j username
    password = "password"  # Update with your Neo4j password

    connector = Neo4jConnector(uri, user, password)

    while True:
        print("1. Create Node")
        print("2. Display Nodes")
        print("3. Get Nodes by Processing Flag")
        print("4. Update Node")
        print("5. Quit")

        choice = input("Enter your choice: ")

        if choice == "1":
            sender = input("Enter sender: ")
            receiver = input("Enter receiver: ")
            message = input("Enter message: ")
            profile_id = input("Enter profile_id: ")
            rule_type = input("Enter rule_type: ")
            processing_flag = input("Enter processing_flag: ")
            return_name = sender + rule_type + receiver
            create_node(connector, sender, receiver, message, profile_id, rule_type, processing_flag, return_name)

        elif choice == "2":
            display_nodes(connector)

        elif choice == "3":
            user_input = input("Enter the processing flag: ")
            with connector._driver.session() as session:
                nodes = session.read_transaction(get_nodes_by_processing_flag, user_input)

            if nodes:
                print(f"Nodes with processing flag '{user_input}':")
                for node in nodes:
                    print(node)
            else:
                print(f"No nodes found with processing flag '{user_input}'.")

        elif choice == "4":
            return_name = input("Enter return name: ")
            new_profile_id = input("Enter new profile_id: ")
            new_message = input("Enter new message: ")
            new_processing_flag = input("Enter new processing_flag: ")
            with connector.driver.session() as session:
                session.write_transaction(update_node,  new_profile_id, new_message,
                                          new_processing_flag, return_name)
            print("Node updated successfully.")

        elif choice == "5":
            connector.close()
            break


if __name__ == "__main__":
    main()

This was the error from the code

Traceback (most recent call last):
  File "C:\Users\kevin\PycharmProjects\pyneo4j\main.py", line 120, in <module>
    main()
  File "C:\Users\kevin\PycharmProjects\pyneo4j\main.py", line 110, in main
    session.write_transaction(update_node,  new_profile_id, new_message,
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_meta.py", line 209, in inner
    return f(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\session.py", line 791, in write_transaction
    return self._run_transaction(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\session.py", line 550, in _run_transaction
    result = transaction_function(tx, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\kevin\PycharmProjects\pyneo4j\main.py", line 59, in update_node
    tx.run(query,  new_profile_id=new_profile_id, new_message=new_message,
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\transaction.py", line 164, in run
    result._tx_ready_run(query, parameters)
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\result.py", line 116, in _tx_ready_run
    self._run(query, parameters, None, None, None, None, None, None)
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\result.py", line 166, in _run
    self._attach()
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\work\result.py", line 274, in _attach
    self._connection.fetch_message()
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\io\_common.py", line 180, in inner
    func(*args, **kwargs)
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\io\_bolt.py", line 851, in fetch_message
    res = self._process_message(tag, fields)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\io\_bolt5.py", line 376, in _process_message
    response.on_failure(summary_metadata or {})
  File "C:\Users\kevin\PycharmProjects\pyneo4j\venv\Lib\site-packages\neo4j\_sync\io\_common.py", line 247, in on_failure
    raise Neo4jError.hydrate(**metadata)
neo4j.exceptions.CypherSyntaxError: {code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input 'n': expected
  "!="
  "%"
  "*"
  "+"
  "-"
  "."
  "/"
  ":"
  "<"
  "<="
  "<>"
  "="
  "=~"
  ">"
  ">="
  "AND"
  "CALL"
  "CONTAINS"
  "CREATE"
  "DELETE"
  "DETACH"
  "ENDS"
  "FOREACH"
  "IN"
  "IS"
  "LOAD"
  "MATCH"
  "MERGE"
  "OPTIONAL"
  "OR"
  "REMOVE"
  "RETURN"
  "SET"
  "STARTS"
  "UNION"
  "UNWIND"
  "USE"
  "WITH"
  "XOR"
  "["
  "^"
  <EOF> (line 1, column 50 (offset: 49))
"MATCH (n) WHERE return_name(n) = $return_nameSET n.profile_id = $new_profile_id,     n.message = $new_message,     n.processing_flag = $new_processing_flag"
                                                  ^}

Upvotes: 0

Views: 345

Answers (3)

Jonathan Giffard
Jonathan Giffard

Reputation: 1

As well as the other guidance already given, you might want to try using .execute_query with the Python driver. See https://neo4j.com/docs/python-manual/current/query-simple/ for more details

Upvotes: 0

cybersam
cybersam

Reputation: 67044

There are a few errors (and areas for improvement) in your query:

query = (
    "MATCH (n) WHERE return_name(n) = $return_name"
    "SET n.profile_id = $new_profile_id, "
    "    n.message = $new_message, "
    "    n.processing_flag = $new_processing_flag "
)
  1. As $jose_bacoy stated, return_name(n) should be n.return_name, since return_name is a property of Message nodes, and Cypher has no return_name function.

  2. query must have whitespace before the SET clause. Your query string contains the snippet ... $return_nameSET ..., which has no whitespace before SET, so the query will fail to parse properly. You can actually see this issue in the query shown by the error message.

  3. For efficiency and to avoid unintentional matches, you should use the node label Message to qualify n. That is, MATCH (n:Message) instead of MATCH (n).

Here is a corrected version of your query:

query = (
    "MATCH (n:Message) WHERE n.return_name = $return_name "
    "SET n.profile_id = $new_profile_id, "
    "    n.message = $new_message, "
    "    n.processing_flag = $new_processing_flag "
)

Upvotes: 0

jose_bacoy
jose_bacoy

Reputation: 12714

The code return_name(n) should be n.return_name

Upvotes: 0

Related Questions