First of all I'm new here, so I apologise if this is an easy question for some of you. I'm trying to use parameters in a py2neo query, however I'm getting an error I'm not sure how to go about fixing. First of all here's a version of the query and function working without any parameters:
def link_nodes_from_csv(graph):
# https://drive.google.com/uc?id=id&export=download
query = """
LOAD CSV WITH HEADERS FROM "https://drive.google.com/uc?id=id&export=download" AS line
FIELDTERMINATOR '\t'
MATCH (ll:LessonLearnedId{id:line.lesson_id})
MATCH (lessonTopic:LessonLearnedTopic{id:line.topic_id})
CALL apoc.create.relationship(lessonTopic, line.lesson_id,{}, ll) YIELD rel
REMOVE rel.noOp
"""
result = graph.run(query)
nodes = [n for n in result]
print(nodes)
This works successfully and I'm able to create the relationships I need. You can see that the relationship names are the same as the id of a lesson (column name lesson_id). Now I need to use the node_from
, node_to
and rel_label
as they hold the parameters I need, so now my function and query looks like such:
# node_from/node_to: dictionary {node_type, attribute, column header }
def link_nodes_from_csv(graph, node_from, node_to, rel_label):
query = """
LOAD CSV WITH HEADERS FROM "https://drive.google.com/uc?id=id&export=download" AS line
FIELDTERMINATOR '\t'
MATCH (n:{node_from[0]}) WHERE n.{node_from[1]}=line.{node_from[2]}
MATCH (m:{node_to[0]}) WHERE m.{node_to[1]} = line.{node_to[2]}
CALL apoc.create.relationship(m, line.{rel_label},{}, n) YIELD rel
REMOVE rel.noOp
"""
result = graph.run(query)
nodes = [n for n in result]
print(nodes)
This query gives me the following error:
I also attempted the following:
# node_from/node_to: dictionary {node_type, attribute, column header }
def link_nodes_from_csv(graph, node_from, node_to, rel_label):
query = """
LOAD CSV WITH HEADERS FROM "https://drive.google.com/uc?id=id&export=download" AS line
FIELDTERMINATOR '\t'
MATCH (n:{param1}) WHERE n.{param2}=line.{param3}
MATCH (m:{param4}) WHERE m.{param5} = line.{param6}
CALL apoc.create.relationship(m, line.{param7},{}, n) YIELD rel
REMOVE rel.noOp
"""
result = graph.run(query, parameters={"param1":node_from[0], "param2": node_from[1], "param3": node_from[2],
"param4": node_to[0], "param5": node_to[1], "param6": node_to[2],
"param7": rel_label})
nodes = [n for n in result]
print(nodes)
However, this gives me more or less the same error:
Finally, I attempted this:
# node_from/node_to: dictionary {node_type, attribute, column header }
def link_nodes_from_csv(graph, node_from, node_to, rel_label):
query = """
LOAD CSV WITH HEADERS FROM "https://drive.google.com/uc?id=id&export=download" AS line
FIELDTERMINATOR '\t'
MATCH (n:LessonLearnedId) WHERE n.{param2}=line.{param3}
MATCH (m:LessonLearnedTopic) WHERE m.{param5} = line.{param6}
CALL apoc.create.relationship(m, line.{param7},{}, n) YIELD rel
REMOVE rel.noOp
"""
result = graph.run(query, parameters={"param2": node_from[1], "param3": node_from[2], "param5": node_to[1],
"param6": node_to[2], "param7": rel_label})
nodes = [n for n in result]
print(nodes)
However this gives me the same error as well:
raise self._failure
py2neo.errors.ClientError: [Statement.SyntaxError] Invalid input '{': expected an identifier, whitespace, a function name or a property key name (line 4, column 51 (offset: 214))
" MATCH (n:LessonLearnedId) WHERE n.{param2}=line.{param3}"
^
I'm not really sure how to go about solving this. Any help is very much appreciated. I can also provide other information, however I'm not sure what exactly would help, so please ask if you need anything from me that would help figuring this out. Thank you very much.
I have generally seen parameters used to represent values, not keys. I am not sure they can work they way you are intending.
I wonder if you might rethink your data model. If you have many values for lessonTopic in your CSV, it doesn't seem like a good choice for a relationship type. This free course might give you some inspiration. https://neo4j.com/graphacademy/training-gdm-40/enrollment/
If you really want dynamic Cypher, you can insert property keys and relationship types into the query string using Python string formatting methods, and then pass the query to graph.run().