简体   繁体   中英

Correct way of using parameters in py2neo Cypher query

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: ![图片|690x50, 100%](上传://LXg4rLxkfMb8WvTOEvuLsee3Wp.png)

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: ![图片|690x67](上传://kN3xCfNHYPNCDZufVJATOJReaNL.png)

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().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM