Neo4j Python Driver Using Unwind with a list of dictionaries

746 views Asked by At

I'm trying to batch merge to create multiple nodes. Using the below code,

def test_batches(tx,user_batch):
            result= tx.run(f"Unwind {user_batch} as user\
                           MERGE (n:User {{id: user.id, name: user.name, username: user.username }})")

However I am getting this error. Note I'm passing in a list of dictionaries.

CypherSyntaxError: {code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input '[': expected "+" or "-" (line 1, column 8 (offset: 7))
"Unwind [{'id': 1596859520977969156, 'name': 'Bigspuds', 'username': 'bigspuds777'}, {'id': 1596860505662144513, 'name': 'JOHN VIEIRA', 'username': 'JOHNVIE67080352'}, {'id': 1596860610905448449, 'name': 'biru nkumat', 'username': 'NkumatB'}, {'id': 1513497734711738374, 'name': 'elfiranda Hakim', 'username': 'Kidonk182'}, {'id': 1596836234860859392, 'name': 'Ecat Miao', 'username': 'sylvanasMa'}] as user                           MERGE (n:User {id: user.id, name: user.name, username: user.username })"
        ^}

I have no idea why this is happening any help is greatly appreciated.

2

There are 2 answers

0
jose_bacoy On BEST ANSWER

Below is a working code on using UNWIND for a list of dictionaries. Please note that is it recommended to pass the value as a parameter rather than working on the value string in query.

from neo4j import GraphDatabase

uri = "neo4j://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "awesomepassword"))

def test_batches(tx, user_batch):
    tx.run("UNWIND $user_batch as user \
            MERGE (n:User {id: user.id, name: user.name, username: user.username})", user_batch=user_batch)
    
with driver.session() as session:
    user_batch = [
                 {'id': 1596859520977969156, 'name': 'Bigspuds', 'username': 'bigspuds777'}, 
                 {'id': 1596860505662144513, 'name': 'JOHN VIEIRA', 'username': 'JOHNVIE67080352'}, 
                 {'id': 1596860610905448449, 'name': 'biru nkumat', 'username': 'NkumatB'}, 
                 {'id': 1513497734711738374, 'name': 'elfiranda Hakim', 'username': 'Kidonk182'}, 
                 {'id': 1596836234860859392, 'name': 'Ecat Miao', 'username': 'sylvanasMa'}]
    session.write_transaction(test_batches, user_batch) 

driver.close()

sample result: enter image description here

1
Frederik Bruun On

You may need to adjust the syntax of the Cypher query to conform to the Neo4j Cypher query language specification. For example, the MERGE clause should use the ON CREATE and ON MATCH syntax to specify the actions that should be taken if the node already exists or not.

Here is an example of how the Cypher query can be rewritten to use the ON CREATE and ON MATCH syntax:

def test_batches(tx,user_batch):
    result = tx.run(f"UNWIND {user_batch} as user
    MERGE (n:User {{id: user.id, name: user.name, username: user.username }})
    ON CREATE SET n = user
    ON MATCH SET n += user")