Search code examples
pythonneo4jcypherpy2neo

How to declare a unique contraint with py2neo


I need ot enforce a unique contraint on my graph database. I found the following method:

graph.schema.create_uniqueness_constraint("Website", "url") 

But it yields the following error:

graph.schema.create_uniqueness_constraint("Website", "url")
AttributeError: 'Schema' object has no attribute 'create_uniqueness_constraint' 

My import and graph instentiation is:

from py2neo import neo4j,node 
graph = neo4j.GraphDatabaseService("http://localhost:7474/db/data/") 

What am I doing wrong, and how can I fix it?

Also, what's the simplest, cleanest way to add a uniqueness constraint with py2neo?

I'm getting confused with the abundance of methods, which sometime seem to fail without reason (couldn't find a comprehensive tutorial on py2neo), and I start to feel like I would be better off writing raw Cypher queries...


Solution

  • It looks like you're on py2neo version 1.x and reading the docs for version 2.0. In py2neo 2.0:

    from py2neo import Graph
    graph = Graph()
    graph.schema.create_uniqueness_constraint('Website', 'url')
    

    In py2neo 1.x, I'm not sure there's a method for creating uniqueness constraints. You'll probably have to do:

    from py2neo import neo4j
    graph = neo4j.GraphDatabaseService("http://localhost:7474/db/data/") 
    neo4j.CypherQuery(graph, 'CREATE CONSTRAINT ON (w:Website) ASSERT w.url IS UNIQUE;').run()
    

    EDIT: Updates per the questions in the comments below. OP is on py2neo 2.0.

    Neo4j doesn't allow you to create a uniqueness constraint without specifying a label. However, this will be easy to accomplish in py2neo. You can use graph.node_labels to get a list of all the labels in your graph, then you can iterate over those and create a uniqueness constraint on each label with the given property:

    from py2neo import Graph
    graph = Graph()
    
    labels = graph.node_labels
    
    for label in labels:
        graph.schema.create_uniqueness_constraint(label, 'url')
    

    Note that this will fail with a py2neo.error.ConstraintViolationException if the constraint already exists; you might want to wrap it in a try-except:

    for label in labels:
        try:
            graph.schema.create_uniqueness_constraint(label, 'url')
        except:
            pass