I am doing a quick proof-of-concept app.
I've been using session.run() to send queries for creating/updating nodes and relationships.
But I can't get it to work for deleting relationships.
my code is essentially:
query = (
"MATCH({name:$n1})-[r:is_related_to]->({name:$n2}) "
"DELETE r"
)
with app_driver.session() as session:
session.run(query, n1=name1, n2=name2)
I've tried the cypher syntax on neo4j's interface and it works.
MATCH ({name:"John"})-[r:is_related_to]->({name:"Jane"})
DELETE r
Please advise.
Thanks!
I am not entirely sure, but I think session.run() returns a Result object. Normally you would iterate over the result records returned. In this case, since you don't expect any data back from your query, can you try if adding .consume() helps:
with app_driver.session() as session:
session.run(query, n1=name1, n2=name2).consume()
Docs mention "content is fetched lazily as consumed by the client application" that is why I suspect consume is needed: API Documentation — Neo4j Python Driver 5.12
Hi and thanks for reaching out.
I tried to reproduce your problem but couldn't. Here's what I did
import neo4j
URL = "neo4j://localhost:7687"
AUTH = ("neo4j", "pass")
DB = "neo4j"
def print_db_stats(driver: neo4j.Driver):
print(
"Number of nodes:",
driver.execute_query(
"MATCH (n) RETURN count(n) AS count",
database_=DB,
result_transformer_=lambda r: r.single(strict=True)["count"],
)
)
print(
"Number of relationships:",
driver.execute_query(
"MATCH ()-[r]->() RETURN count(r) AS count",
database_=DB,
result_transformer_=lambda r: r.single(strict=True)["count"],
)
)
def main():
with neo4j.GraphDatabase.driver(URL, auth=AUTH) as driver:
# wiping the db and creating some dummy data
driver.execute_query("MATCH (n) DETACH DELETE n", database_=DB)
print(
driver.execute_query(
"UNWIND range(0, 999) AS i "
"MERGE (p1:Person {name: 'Name ' + i}) "
"MERGE (p2:Person {name: 'Name ' + ((i + 1) % 1000)}) "
"CREATE (p1)-[:IS_RELATED_TO]->(p2)",
database_=DB,
).summary.counters
)
# check how many nodes and relationships we have
print_db_stats(driver)
# +++ your code +++
with driver.session(database=DB) as session:
session.run(
"MATCH({name:$n1})-[r:IS_RELATED_TO]->({name:$n2}) "
"DELETE r",
n1="Name 0",
n2="Name 1",
)
# check again
print_db_stats(driver)
if __name__ == "__main__":
main()
and this is what it prints
{'_contains_updates': True, 'labels_added': 1000, 'relationships_created': 1000, 'nodes_created': 1000, 'properties_set': 1000}
Number of nodes: 1000
Number of relationships: 1000
Number of nodes: 1000
Number of relationships: 999
As you can see it deleted exactly one relationship as expected. Can you adjust my example or elaborate on yours so that I'm able to reproduce the issue, please?
Thank you guys so much for the insight and help.
I found my mistake.
I assumed that my part of the code was working correctly. I sent the wrong information in the query.
Since the relationship is directional,
(a)-is_related_to->(b),
my query was trying to match (b)-is_related_to->(a) which doesn't exist. I am now trying to trace why the wrong information was sent.
Sorry for this noob mistake.