Dry run queries in CE

I am using CE 5.14 and want to know if there's any way I can run a query to see what changes would be made, but without actually making those changes to the database.

I build knowledge grapghs from customer provided .csv files by running Python scripts to process them and generate Cypher queries that create the nodes and relationships. These files are not always in great shape, and the Python does a fair bit of validation, but can't do everything. For example, typically, there is a uniqueness constraint on one of the node properties and I'd like to be to check if there would be any constraint violations.

Is there a way of doing this sort of check?

Maybe you can try with an Explicit transaction and roll back? API Documentation — Neo4j Python Driver 5.26

In my db, I have a Person node with id:1, with this code

for i in [1,2]:
    with driver.session(database=DB_NAME).begin_transaction() as tx:
        try:
            result = tx.run('''
                            create(n:Person{id:$id})
                            return count(*) as nodes_created
                            ''', id=i)
            print(result.data())
        except Exception as e: 
            print(e)
        finally:
            if not tx.closed():
                tx.rollback()

I get:

{code: Neo.ClientError.Schema.ConstraintValidationFailed} {message: Node(0) already exists with label `Person` and property `id` = 1}
[{'nodes_created': 1}]

But in terms of writing to the graph, I think it is better to "know the constraints" and make sure you use merge when needed.

I don't think so. An alternative to Håkan's answer is to utilize the help queries listed in the documentation for finding nodes/relationships that violates the constraint, table 3 in this section. They are very generic but can be adapted to fit with your given labels/relationship types/properties (and adding load csv or similar).

To clarify, my writes usually look like this:

records, summary, keys = driver.execute_query(
    ''' 
        unwind $rows as row
        merge(n:Person{id:row.id})
        on create set n.name = row.name
        return count(*) as nodes_created
    ''',
    database_=DB_NAME,
    routing_=RoutingControl.WRITE,
    rows = [{'id':1, 'name':'A'} , {'id':2, 'name': 'B'} ]
)
print(summary.counters)

print out:

{'_contains_updates': True, 'labels_added': 1, 'nodes_created': 1, 'properties_set': 1}

Thanks Håken, I think I can adapt your solution for my problem :slight_smile:

And also thanks Therese for pointing me at the documentation.

2 Likes