Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
05-11-2021 10:09 PM
I want to create a method that accepts the names of two nodes and a relationship type name, and creates a relationship of that type between the nodes. I'm having trouble figuring out how to reference the relationship name that I'm passing into the method within my query. The version I tried below gives me an error: Invalid input '$': expected whitespace or a rel type name
.
Does anyone know how I can create the relationship with the argument that gets passed in to the method?
def create_relationship(tx, node1_name, node2_name, rel_type):
query = (
"MATCH (n1:Resource) "
"WITH n1 "
"MATCH (n2:Resource) "
"WHERE n1.name = $node1_name AND n2.name = $node2_name "
"MERGE (n1)-[r:$rel_type]->(n2) "
"RETURN n1, n2, r"
)
result = tx.run(query, node1_name=node1_name, node2_name=node2_name)
try:
return [{"n1": record["n1"]["name"], "n2": record["n2"]["name"], "r":record["r"]}
for record in result]
except ServiceUnavailable as exception:
logging.error("{query} raised an error: \n {exception}".format(
query=query, exception=exception))
raise
with driver.session() as session:
result = session.write_transaction(create_relationship, "Florence", "piazzale Michelangelo", "CONTAINS_POI")
for record in result:
print("Created {r} relationship between: {n1} and {n2}".format(
r=record['r'], n1=record['n1'], n2=record['n2']))
driver.close()
05-13-2021 04:24 AM
So there's a couple of things going on here the first is you aren't submitting a parameter called rel_type when you do this:
result = tx.run(query, node1_name=node1_name, node2_name=node2_name)
Second -- I think you can't use cypher parameters for labels and reltypes, that kind of parameter interpolation doesn't work in cypher. You might need to convert the relationship to a map and check its type key
05-13-2021 04:50 PM
Thank you! You're right, I neglected to pass in the rel_type param when actually calling the method. I also found an APOC method that I could use to get the functionality I want: apoc.create.relationship - APOC Documentation. Here's what my method looks like now, in case it helps anyone in the future:
def create_relationship(tx, node1_name, node2_name, rel_type):
query = (
"MATCH (n1:Resource) "
"WITH n1 "
"MATCH (n2:Resource) "
"WHERE n1.name = $node1_name AND n2.name = $node2_name "
"CALL apoc.create.relationship(n1, $rel_type, {}, n2) YIELD rel "
"RETURN n1, n2, rel"
)
result = tx.run(query, node1_name=node1_name, node2_name=node2_name, rel_type=rel_type)
try:
return [{"n1": record["n1"]["name"], "n2": record["n2"]["name"], "r": record["rel"].type}
for record in result]
except ServiceUnavailable as exception:
logging.error("{query} raised an error: \n {exception}".format(
query=query, exception=exception))
raise
All the sessions of the conference are now available online