How can I add string variables into SET request using official Neo4j Python Drive?

Since py2neo isn't quite compatible with the latest Neo4j, I chose to use the official Neo4j Python Driver.

My purpose

I've been trying to add a string variable into the Driver.execute_query() method's cypher SET request.

My purpose is using Neo4j-python-drive to give some specific nodes another key "content" and set its value equals to an input string variable(node. Content = input_string_variable).

Which is turn (n:Log {id: 'log_001-02'}) into (n:Log {id: 'log_001-02', content: my_input_log_string}).

Now every node in my database has given a unique value of key "id", so I search any (node) by node.id.

information

python & Neo4j version

> python -V 
Python 3.11.3
> pip show neo4j
Name: neo4j
Version: 5.10.0
Summary: Neo4j Bolt driver for Python
Home-page:
Author:
Author-email: "Neo4j, Inc." <drivers@neo4j.com>
License: Apache License, Version 2.0
Location: D:\miniconda3\envs\coderunnew\Lib\site-packages
Requires: pytz
Required-by:

My code

import neo4j
from neo4j import GraphDatabase, RoutingControl, Driver
# from neo4j.exceptions import DriverError, Neo4jError
import logging
import sys
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
logging.getLogger("neo4j").addHandler(handler)
logging.getLogger("neo4j").setLevel(logging.DEBUG)
URI = "neo4j://127.0.0.1:7687"
AUTH = ("neo4j", "!neo4j")
database_name = "neo4j"

def add_node(driver: Driver, target_node_id: str):
    driver.execute_query(
        "CREATE (n {id: $target_node_id})",
        target_node_id = target_node_id, 
        database_ = 'neo4j',
    )

def add_node_content(driver: Driver, target_node_isd: str, content_to_be_added: str):
    driver.execute_query(
        "MATCH (n {id: $target_node_id})"
        "SET n.content= $content_to_be_added",
        target_node_id = target_node_id, content_to_be_added = content_to_be_added,
        database_ = 'neo4j',
    )

with GraphDatabase.driver(URI, auth=AUTH, trusted_certificates = neo4j.TrustAll()) as driver:
    driver.verify_connectivity()
    add_node(driver, 'test_id')
    add_node_content(driver, 'test_id', 'content_text')

Error Massage

  File "D:\test_neo4j.py", line 22, in add_node_content
    driver.execute_query(
  File "D:\test_neo4j.py", line 32, in <module>
    add_node_content(driver, 'test_id', 'content_text')
neo4j.exceptions.CypherSyntaxError: {code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input '{': expected "+" or "-" (line 1, column 47 (offset: 46))
"MATCH (n {id: $target_node_id})SET n.content= {content_to_be_added}"
                                               ^}

Log Massage

I selected some of the log about the error below.

>> [#DAC1]  _: <CONNECTION> state: READY > TX_READY_OR_TX_STREAMING
>> [#DAC1]  C: RUN 'MATCH (n {id: $target_node_id})SET n.content= {content_to_be_added}' {'target_node_id': 'test_id', 'content_to_be_added': 'content_text'} {}
>> [#DAC1]  C: PULL {'n': 1000}
>> [#DAC1]  S: FAILURE {'code': 'Neo.ClientError.Statement.SyntaxError', 'message': 'Invalid input \'{\': expected "+" or "-" (line 1, column 47 (offset: 46))\r\n"MATCH (n {id: $target_node_id})SET n.content= {content_to_be_added}"\r\n                                               ^'}
>> [#DAC1]  C: RESET
>> [#DAC1]  S: IGNORED
>> [#DAC1]  S: SUCCESS {}
>> [#DAC1]  _: <CONNECTION> state: FAILED > READY

isn't it just that you forgot $ before content_to_be_added ?

First of all thank you for the really extensive report with logs and version infos and everything :raised_hands: It's a blast to work with such detailed information and makes it much easier to help!

Looking at the code, I can't see a problem either. But if you look at the error message and in the logs, you'll see that the driver sent

MATCH (n {id: $target_node_id})SET n.content= {content_to_be_added}

instead of

MATCH (n {id: $target_node_id})SET n.content= $content_to_be_added

So as v2belleville pointed out, you're missing the $. Make sure you're running the right script, have all changes saved and so on.

The code you posted works for me almost as is. There's just a typo where it says target_node_isdinstead of target_node_id.