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 choose to use the official Python Driver.
I've been trying to add a string variable into the Driver.execute_query()
method's cypher SET
request.
> 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_id: 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')
Now every node in my database has given a unique value of key "id", so I search any (node)
by node.id
.
My purpose is to give some specific nodes another key "content" and set its value equals to a input string variable(node.content=input_string_variable
).
Error Massage from VS Code:
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:
>> [#0000] _: <POOL> created, routing address IPv4Address(('127.0.0.1', 7687))
>> [#0000] _: <WORKSPACE> resolve home database
>> [#0000] _: <POOL> attempting to update routing table from IPv4Address(('127.0.0.1', 7687))
>> [#0000] _: <RESOLVE> in: 127.0.0.1:7687
>> [#0000] _: <RESOLVE> dns resolver out: 127.0.0.1:7687
>> [#0000] _: <POOL> _acquire router connection, database=None, address=ResolvedIPv4Address(('127.0.0.1', 7687))
>> [#0000] _: <POOL> trying to hand out new connection
>> [#0000] C: <OPEN> 127.0.0.1:7687
>> [#DAC1] C: <MAGIC> 0x6060B017
>> [#DAC1] C: <HANDSHAKE> 0x00030305 0x00020404 0x00000104 0x00000003
>> [#DAC1] S: <HANDSHAKE> 0x00000305
>> [#DAC1] C: HELLO {'user_agent': 'neo4j-python/5.10.0 Python/3.11.3-final-0 (win32)', 'routing': {'address': '127.0.0.1:7687'}, 'bolt_agent': {'product': 'neo4j-python/5.10.0', 'platform': 'Windows 10; AMD64', 'language': 'Python/3.11.3-final-0', 'language_details': 'CPython; 3.11.3-final-0 (main, May 15 2023 15:41:31) [MSC v.1916 64 bit (AMD64)]'}}
>> [#DAC1] C: LOGON {'scheme': 'basic', 'principal': 'neo4j', 'credentials': '*******'}
>> [#DAC1] S: SUCCESS {'server': 'Neo4j/5.10.0', 'connection_id': 'bolt-14', 'hints': {'connection.recv_timeout_seconds': 120}}
>> [#DAC1] _: <CONNECTION> state: CONNECTED > AUTHENTICATION
>> [#DAC1] S: SUCCESS {}
>> [#DAC1] _: <CONNECTION> state: AUTHENTICATION > READY
>> [#DAC1] C: ROUTE {'address': '127.0.0.1:7687'} () {}
>> [#DAC1] S: SUCCESS {'rt': {'servers': [{'addresses': ['127.0.0.1:7687'], 'role': 'WRITE'}, {'addresses': ['127.0.0.1:7687'], 'role': 'READ'}, {'addresses': ['127.0.0.1:7687'], 'role': 'ROUTE'}], 'ttl': 300, 'db': 'neo4j'}}
>> [#DAC1] _: <POOL> released bolt-14
>> [#0000] _: <ROUTING> updated table=RoutingTable(database='neo4j' routers={IPv4Address(('127.0.0.1', 7687))}, readers={IPv4Address(('127.0.0.1', 7687))}, writers={IPv4Address(('127.0.0.1', 7687))}, last_updated_time=171526.6790538, ttl=300)
>> [#0000] _: <POOL> update routing table from address=ResolvedIPv4Address(('127.0.0.1', 7687)) (RoutingTable(database='neo4j' routers={IPv4Address(('127.0.0.1', 7687))}, readers={IPv4Address(('127.0.0.1', 7687))}, writers={IPv4Address(('127.0.0.1', 7687))}, last_updated_time=171526.6790538, ttl=300))
>> [#0000] _: <POOL> acquire routing connection, access_mode='READ', database='neo4j'
>> [#0000] _: <POOL> routing aged?, database=None
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.63341, ttl=0, perf_time=171526.6807677 => False
>> [#0000] _: <POOL> routing aged?, database=neo4j
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.6790538, ttl=300, perf_time=171526.6813498 => False
>> [#0000] _: <ROUTING> checking table freshness (readonly=True): table expired=False, has_server_for_mode=True, table routers={IPv4Address(('127.0.0.1', 7687))} => True
>> [#0000] _: <POOL> using existing routing table RoutingTable(database='neo4j' routers={IPv4Address(('127.0.0.1', 7687))}, readers={IPv4Address(('127.0.0.1', 7687))}, writers={IPv4Address(('127.0.0.1', 7687))}, last_updated_time=171526.6790538, ttl=300)
>> [#0000] _: <POOL> acquire address, database='neo4j' address=IPv4Address(('127.0.0.1', 7687))
>> [#DAC1] _: <POOL> liveness check
>> [#DAC1] C: RESET
>> [#DAC1] S: SUCCESS {}
>> [#DAC1] _: <POOL> picked existing connection bolt-14
>> [#DAC1] _: <POOL> checked re_auth auth=None updated=False force=False
>> [#DAC1] _: <POOL> handing out existing connection
>> [#DAC1] _: <POOL> released bolt-14
>> [#0000] _: <POOL> acquire routing connection, access_mode='WRITE', database='neo4j'
>> [#0000] _: <POOL> routing aged?, database=None
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.63341, ttl=0, perf_time=171526.6866407 => False
>> [#0000] _: <POOL> routing aged?, database=neo4j
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.6790538, ttl=300, perf_time=171526.687203 => False
>> [#0000] _: <ROUTING> checking table freshness (readonly=False): table expired=False, has_server_for_mode=True, table routers={IPv4Address(('127.0.0.1', 7687))} => True
>> [#0000] _: <POOL> using existing routing table RoutingTable(database='neo4j' routers={IPv4Address(('127.0.0.1', 7687))}, readers={IPv4Address(('127.0.0.1', 7687))}, writers={IPv4Address(('127.0.0.1', 7687))}, last_updated_time=171526.6790538, ttl=300)
>> [#0000] _: <POOL> acquire address, database='neo4j' address=IPv4Address(('127.0.0.1', 7687))
>> [#DAC1] _: <POOL> picked existing connection bolt-14
>> [#DAC1] _: <POOL> checked re_auth auth=None updated=False force=False
>> [#DAC1] _: <POOL> handing out existing connection
>> [#DAC1] C: BEGIN {'db': 'neo4j'}
>> [#DAC1] S: SUCCESS {}
>> [#DAC1] _: <CONNECTION> state: READY > TX_READY_OR_TX_STREAMING
>> [#DAC1] C: RUN 'CREATE (n {id: $target_node_id})' {'target_node_id': 'test_id'} {}
>> [#DAC1] C: PULL {'n': 1000}
>> [#DAC1] S: SUCCESS {'t_first': 3, 'fields': [], 'qid': 0}
>> [#DAC1] S: SUCCESS {'stats': {'contains-updates': True, 'nodes-created': 1, 'properties-set': 1}, 'type': 'w', 't_last': 0, 'db': 'neo4j'}
>> [#DAC1] C: COMMIT
>> [#DAC1] S: SUCCESS {'bookmark': 'FB:kcwQX/44Cf2sTYCaOP0gmu8R8MoAAhrckA=='}
>> [#DAC1] _: <CONNECTION> state: TX_READY_OR_TX_STREAMING > READY
>> [#DAC1] _: <POOL> released bolt-14
>> [#0000] _: <POOL> acquire routing connection, access_mode='WRITE', database='neo4j'
>> [#0000] _: <POOL> routing aged?, database=None
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.63341, ttl=0, perf_time=171526.7093517 => False
>> [#0000] _: <POOL> routing aged?, database=neo4j
>> [#0000] _: <ROUTING> purge check: last_updated_time=171526.6790538, ttl=300, perf_time=171526.7100152 => False
>> [#0000] _: <ROUTING> checking table freshness (readonly=False): table expired=False, has_server_for_mode=True, table routers={IPv4Address(('127.0.0.1', 7687))} => True
>> [#0000] _: <POOL> using existing routing table RoutingTable(database='neo4j' routers={IPv4Address(('127.0.0.1', 7687))}, readers={IPv4Address(('127.0.0.1', 7687))}, writers={IPv4Address(('127.0.0.1', 7687))}, last_updated_time=171526.6790538, ttl=300)
>> [#0000] _: <POOL> acquire address, database='neo4j' address=IPv4Address(('127.0.0.1', 7687))
>> [#DAC1] _: <POOL> picked existing connection bolt-14
>> [#DAC1] _: <POOL> checked re_auth auth=None updated=False force=False
>> [#DAC1] _: <POOL> handing out existing connection
>> [#DAC1] C: BEGIN {'db': 'neo4j', 'bookmarks': ['FB:kcwQX/44Cf2sTYCaOP0gmu8R8MoAAhrckA==']}
>> [#DAC1] S: SUCCESS {}
>> [#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
>> [#DAC1] _: <POOL> released bolt-14
>> [#0000] _: <POOL> close
>> [#DAC1] C: GOODBYE
>> [#DAC1] C: <CLOSE>
Is there any way to achieve my purpose?
Thanks a lot.