Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-09-2020 02:16 AM
from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "pass"))
def add_friend(tx, name, friend_name):
tx.run("MERGE (a:Person {name: $name}) "
"MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})",
name=name, friend_name=friend_name)
def print_friends(tx, name):
for record in tx.run("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
"RETURN friend.name ORDER BY friend.name", name=name):
print(record["friend.name"])
def dictToProperties(properties_dict):
props = ""
for key in properties_dict:
props += key
props += ': '
props += '\''
props += properties_dict[key]
props += '\''
props += ', '
return props[:-2]
def add_node(tx, labels, properties):
tx.run("CREATE (" + ':'.join(labels) + " {" + dictToProperties(properties) + "}) ")
props = {'name': '\' }) \nWITH true as pass\nMATCH (e) DETACH DELETE e RETURN ({e: \''}
print(dictToProperties(props))
with driver.session() as session:
session.write_transaction(add_friend, "Arthur", "Guinevere")
session.write_transaction(add_friend, "Arthur", "Lancelot")
session.write_transaction(add_friend, "Arthur", "Merlin")
session.write_transaction(add_node, ['Person', 'Swedish'], props)
session.read_transaction(print_friends, "Arthur") # (nothing to print)
driver.close()
The neo4j python driver provides this sort of "injection" protection, right ?
I wish it provided this kind of idiomatic function (add_node
) that I'm trying to implement.
01-09-2020 03:35 AM
Hello Wis, welcome to the community. What do you mean by make this not dangerous? You're correct it's not possible to dynamically create nodes in the graph the way that you're trying to do, but that's probably for the best from a schema integrity point of view. In my experience it helps to know exactly what transactions are being run, etc.
01-09-2020 04:00 AM
Hi @MuddyBootsCode sorry for not being clear.
look at the value of name
in the props
dictionary, it causes what is commonly/popularly known as an "sql injection".
it's possible, but I agree with you it may not be good practice and that you need a schema model in code, preferably with an Object Graph Mapper (OGM).
for now I think I fixed it by making it return the records in the query and the method, like so:
def add_node(tx, labels, properties):
return tx.run(
"CREATE (p:"
+ ":".join(labels)
+ " {"
+ dictToProperties(properties)
+ "}) RETURN p"
)
now the parser returns this error with a python exception that I can catch:
neobolt.exceptions.CypherSyntaxError: RETURN can only be used at the end of the query (line 3, column 27 (offset: 83))
"MATCH (e) DETACH DELETE e RETURN ({e: ''}) RETURN p"
01-09-2020 04:03 AM
Ah, gotcha. Looks like you've got it figured out. Nice implementation.
All the sessions of the conference are now available online