eli0T
eli0T

Reputation: 81

Catch a Neo4j exception

I can't catch a ConstraintError exception.

When I run this:

try:
    tx.run('MERGE (:Person {{name:"{name}",country:"{country}"}})'.format(name=name,country=country))
except ConstraintViolation:
    pass

the exception is still raised.

I tried

from neo4j.v1 import exceptions

and also ConstraintError and ConstraintViolation.

However, wether I try to catch ConstraintError or ConstraintViolation I get this error:

ConstraintError: Node(5314) already exists with label `Person` and property `name` = 'SomeThing'

How can I handle this properly ?

Upvotes: 2

Views: 2942

Answers (2)

JJones
JJones

Reputation: 843

I had the same problem and found that the reason that the exception was not being hit was that the neo4j driver does not raise the exception until the session is closed.

It's not in the code above but I assume that you had previously opened a sesssion - something like

session = driver.session()

if you move your session.close into the try block then you should hit the exception

session = driver.session()

session.run("MATCH (n) DETACH DELETE n")
session.run("CREATE CONSTRAINT ON (n:Person) ASSERT n.name IS UNIQUE")
try:
    session.run("CREATE (n:Person {name:'Bob'})")
    session.run("CREATE (n:Person {name:'Bob'})")
    session.close()
except:
    print("Error")

Upvotes: 2

cybersam
cybersam

Reputation: 66999

Suppose this node already exists (I use string literals instead of parameters, for clarity):

(:Person {name: "SomeThing", country: "Canada"})

and you make this request:

MERGE (:Person {name: "SomeThing", country: "USA"})

You would get a ConstraintError because such a node does not yet exist (with both property values), and yet you also cannot create that node (because of the uniqueness constraint).

Possible Fixes

  • If you want to force the country value to be "USA", no matter what, this should avoid the ConstraintError:

    MERGE (p:Person {name: "SomeThing"})
    SET p.country = "USA";
    
  • Or, if you only want to set the country value if a node with that name value does not yet exist, then this should work:

    MERGE (p:Person {name: "SomeThing"})
    ON CREATE SET p.country = "USA";
    
  • Or, if you only want to set the country value if a node with that name value already exists, then this should work:

    MERGE (p:Person {name: "SomeThing"})
    ON MATCH SET p.country = "USA";
    

Upvotes: 4

Related Questions