API: Cypher

Py2neo provides Cypher execution functionality via the HTTP transactional endpoint or, if unavailable, the legacy endpoint. This is typically accessed via the py2neo.Graph.cypher attribute from where transactions may be created and simple execution may be carried out. Parameterised statements are fully supported and on top of this, an extra layer of client-side presubstitution is available. Such presubstitution is useful for parameterisation of relationship types, node labels and property keys. Angled quotation marks are used for delimiting parameter keys and can be mixed with regular parameters:

from py2neo import Graph
graph = Graph()
cypher = graph.cypher
cypher.execute("CREATE (a {name:{a}})-[:«rel»]->(b:«labels» {name:{b}})",
               a="Alice", rel="KNOWS", labels=["Human Being", "Employee"], b="Bob")

Each presubstitution parameter will be correctly escaped within backticks if necessary and collections passed as a single parameter will be joined by colons. Therefore, the code above is equivalent to:

from py2neo import Graph
graph = Graph()
cypher = graph.cypher
cypher.execute("CREATE (a {name:{a}})-[:KNOWS]->(b:`Human Being`:Employee {name:{b}})",
               a="Alice", b="Bob")

Integer parameters will be substituted directly, without escaping, and integer 2-tuples will be assumed to denote a range:

from py2neo import Graph
graph = Graph()
cypher = graph.cypher
cypher.execute("MATCH (a)-[:KNOWS*«r1»]->(b)-[:KNOWS*«r2»]->(c)", r1=1, r2=(3, 5))

Cypher Resource

class py2neo.cypher.CypherResource[source]

Service wrapper for all Cypher functionality, providing access to transactions (if available) as well as single statement execution and streaming. If the server supports Cypher transactions, these will be used for single statement execution; if not, the vanilla Cypher endpoint will be used.

This class will usually be instantiated via a py2neo.Graph object and will be made available through the py2neo.Graph.cypher attribute. Therefore, for single statement execution, simply use the execute() method:

from py2neo import Graph
graph = Graph()
results = graph.cypher.execute("MATCH (n:Person) RETURN n")
begin()[source]

Begin a new transaction.

Return type:py2neo.cypher.CypherTransaction
execute(statement, parameters=None, **kwparameters)[source]

Execute a single Cypher statement.

Parameters:
  • statement – A Cypher statement to execute.
  • parameters – A dictionary of parameters.
Return type:

py2neo.cypher.RecordList

execute_one(statement, parameters=None, **kwparameters)[source]

Execute a single Cypher statement and return the value from the first column of the first record returned.

Parameters:
  • statement – A Cypher statement to execute.
  • parameters – A dictionary of parameters.
Returns:

Single return value or None.

post(statement, parameters=None, **kwparameters)[source]

Post a Cypher statement to this resource, optionally with parameters.

Parameters:
  • statement – A Cypher statement to execute.
  • parameters – A dictionary of parameters.
  • kwparameters – Extra parameters supplied by keyword.
Return type:

httpstream.Response

run(statement, parameters=None, **kwparameters)[source]

Execute a single Cypher statement, ignoring any return value.

Parameters:
  • statement – A Cypher statement to execute.
  • parameters – A dictionary of parameters.
stream(statement, parameters=None, **kwparameters)[source]

Execute the query and return a result iterator.

Parameters:
  • statement – A Cypher statement to execute.
  • parameters – A dictionary of parameters.
Return type:

py2neo.cypher.RecordStream

Transactions

class py2neo.cypher.CypherTransaction(uri)[source]

A transaction is a transient resource that allows multiple Cypher statements to be executed within a single server transaction.

append(statement, parameters=None, **kwparameters)[source]

Add a statement to the current queue of statements to be executed.

Parameters:
  • statement – the statement to append
  • parameters – a dictionary of execution parameters
commit()[source]

Send all pending statements to the server for execution and commit the transaction.

Returns:list of results from pending statements
error_class

alias of CypherTransactionError

finished

Indicates whether or not this transaction has been completed or is still open.

Returns:True if this transaction has finished, False otherwise
process()[source]

Send all pending statements to the server for execution, leaving the transaction open for further statements. Along with append, this method can be used to batch up a number of individual statements into a single HTTP request:

from py2neo import Graph

graph = Graph()
statement = "MERGE (n:Person {name:{N}}) RETURN n"

tx = graph.cypher.begin()

def add_names(*names):
    for name in names:
        tx.append(statement, {"N": name})
    tx.process()

add_names("Homer", "Marge", "Bart", "Lisa", "Maggie")
add_names("Peter", "Lois", "Chris", "Meg", "Stewie")

tx.commit()
Returns:list of results from pending statements
rollback()[source]

Rollback the current transaction.

Tasks

CypherTasks are self-contained bundles of Cypher statements and parameters intended for use within Cypher transactions.

class py2neo.cypher.CypherTask(statement='', parameters=None, **kwparameters)[source]

The CypherTask class can either be used directly or as a base class for more specific statement implementations.

parameters

Dictionary of parameters.

statement

The Cypher statement.

class py2neo.cypher.CreateNode(*labels, **properties)[source]

CypherTask for creating nodes.

labels

The full set of labels to apply to the created node.

Return type:py2neo.LabelSet
parameters

Dictionary of parameters.

properties

The full set of properties to apply to the created node.

Return type:py2neo.PropertySet
set(*labels, **properties)[source]

Extra labels and properties to apply to the node.

statement

The full Cypher statement.

with_return()[source]

Include a RETURN clause in the statement.

class py2neo.cypher.MergeNode(primary_label, primary_key=None, primary_value=None)[source]

CypherTask for merging nodes.

>>> from py2neo import Graph
>>> graph = Graph()
>>> tx = graph.cypher.begin()
>>> tx.append(MergeNode("Person", "name", "Alice"))
>>> tx.commit()
   | a
---+-----------------------
 1 | (n170 {name:"Alice"})
labels

The full set of labels to apply to the merged node.

Return type:py2neo.LabelSet
parameters

Dictionary of parameters.

primary_key

The property key on which to merge.

primary_label

The label on which to merge.

primary_value

The property value on which to merge.

properties

The full set of properties to apply to the merged node.

Return type:py2neo.PropertySet
set(*labels, **properties)[source]

Extra labels and properties to apply to the node.

>>> merge = MergeNode("Person", "name", "Bob").set("Employee", employee_id=1234)
statement

The full Cypher statement.

with_return()[source]

Include a RETURN clause in the statement.

Records

class py2neo.cypher.Record(values)[source]

A simple object containing values from a single row of a Cypher result. Each value can be retrieved by column position or name, supplied as either an index key or an attribute name.

Consider the record below:

   | person                     | name
---+----------------------------+-------
 1 | (n1:Person {name:"Alice"}) | Alice

If this record is named r, the following expressions are equivalent and will return the value 'Alice':

r[1]
r["name"]
r.name
class py2neo.cypher.RecordList(columns, records)[source]

A list of records returned from the execution of a Cypher statement.

one

The first record from this result, reduced to a single value if that record only consists of a single column. If no records are available, None is returned.

to_subgraph()[source]

Convert a RecordList into a Subgraph.

class py2neo.cypher.RecordStream(graph, response)[source]

An accessor for a sequence of records yielded by a streamed Cypher statement.

for record in graph.cypher.stream("MATCH (n) RETURN n LIMIT 10")
    print record[0]

Each record returned is cast into a namedtuple with names derived from the resulting column names.

Note

Results are available as returned from the server and are decoded incrementally. This means that there is no need to wait for the entire response to be received before processing can occur.

close()[source]

Close results and free resources.

class py2neo.cypher.RecordProducer(columns)[source]
produce(values)[source]

Produce a record from a set of values.

Subgraph

class py2neo.Subgraph(*entities)[source]

A general collection of Node and Relationship objects.

add(entity)[source]

Add an entity to the subgraph.

Parameters:entity – Entity to add
bound

True if all entities in this subgraph are bound to remote counterparts, False otherwise.

exists

True if this subgraph exists in the database, False otherwise.

graph

The parent graph of this subgraph.

Return type:Graph
nodes

The set of all nodes in this subgraph.

order

The number of nodes in this subgraph.

relationships

The set of all relationships in this subgraph.

service_root

The root service associated with this subgraph.

Returns:ServiceRoot
size

The number of relationships in this subgraph.

unbind()[source]

Detach all entities in this subgraph from any remote counterparts.

Builders

class py2neo.cypher.CreateStatement(graph)[source]

Builder for a Cypher CREATE/CREATE UNIQUE statement.

create(entity)[source]

Append an entity to the CREATE clause of this statement.

Parameters:entity – The entity to create.
create_unique(entity)[source]

Append an entity to the CREATE UNIQUE clause of this statement.

Parameters:entity – The entity to add.
execute()[source]

Execute this statement.

Returns:A tuple of created entities.
graph = None

The graph against which this statement is to be executed.

parameters = None

The parameters to inject into this statement.

string

The full Cypher statement as a string.

class py2neo.cypher.DeleteStatement(graph)[source]

Builder for a Cypher DELETE statement.

delete(entity)[source]

Append an entity to the DELETE clause of this statement.

Parameters:entity – The entity to delete.
execute()[source]

Execute this statement.

graph = None

The graph against which this statement is to be executed.

parameters = None

The parameters to inject into this statement.

string

The full Cypher statement as a string.

class py2neo.cypher.CypherWriter(file=None, **kwargs)[source]

Writer for Cypher data. This can be used to write to any file-like object, such as standard output:

>>> from py2neo import Node
>>> from py2neo.cypher import CypherWriter
>>> import sys
>>> writer = CypherWriter(sys.stdout)
>>> writer.write(Node("Person", name="Alice"))
(:Person {name:"Alice"})
write(obj)[source]

Write any entity, value or collection.

write_identifier(identifier)[source]

Write an identifier.

write_label(label)[source]

Write a label.

write_list(collection)[source]

Write a list.

write_literal(text)[source]

Write literal text.

write_map(mapping)[source]

Write a map.

write_node(node, name=None, properties=None)[source]

Write a node.

write_node_pointer(node_pointer)[source]

Write a node.

write_parameter(parameter)[source]

Write a parameter key in curly brackets.

write_path(path)[source]

Write a py2neo.Path.

write_rel(rel, name=None)[source]

Write a relationship (excluding nodes).

write_relationship(relationship, name=None)[source]

Write a relationship (including nodes).

write_value(value)[source]

Write a value.

py2neo.cypher.cypher_escape(identifier)[source]

Escape a Cypher identifier in backticks.

>>> cypher_escape("this is a `label`")
'`this is a ``label```'
py2neo.cypher.cypher_repr(obj)[source]

Generate the Cypher representation of an object.

Exceptions

exception py2neo.cypher.CypherError(message, **kwargs)[source]
exception py2neo.cypher.CypherTransactionError(message, **kwargs)[source]

Client Errors

exception py2neo.cypher.ClientError(message, **kwargs)[source]

The Client sent a bad request - changing the request might yield a successful outcome.

exception py2neo.cypher.error.request.Invalid(message, **kwargs)[source]

The client provided an invalid request.

exception py2neo.cypher.error.request.InvalidFormat(message, **kwargs)[source]

The client provided a request that was missing required fields, or had values that are not allowed.

exception py2neo.cypher.error.schema.ConstraintAlreadyExists(message, **kwargs)[source]

Unable to perform operation because it would clash with a pre-existing constraint.

exception py2neo.cypher.error.schema.ConstraintVerificationFailure(message, **kwargs)[source]

Unable to create constraint because data that exists in the database violates it.

exception py2neo.cypher.error.schema.ConstraintViolation(message, **kwargs)[source]

A constraint imposed by the database was violated.

exception py2neo.cypher.error.schema.IllegalTokenName(message, **kwargs)[source]

A token name, such as a label, relationship type or property key, used is not valid. Tokens cannot be empty strings and cannot be null.

exception py2neo.cypher.error.schema.IndexAlreadyExists(message, **kwargs)[source]

Unable to perform operation because it would clash with a pre-existing index.

exception py2neo.cypher.error.schema.IndexBelongsToConstraint(message, **kwargs)[source]

A requested operation can not be performed on the specified index because the index is part of a constraint. If you want to drop the index, for instance, you must drop the constraint.

exception py2neo.cypher.error.schema.LabelLimitReached(message, **kwargs)[source]

The maximum number of labels supported has been reached, no more labels can be created.

exception py2neo.cypher.error.schema.NoSuchConstraint(message, **kwargs)[source]

The request (directly or indirectly) referred to a constraint that does not exist.

exception py2neo.cypher.error.schema.NoSuchIndex(message, **kwargs)[source]

The request (directly or indirectly) referred to an index that does not exist.

exception py2neo.cypher.error.statement.ArithmeticError(message, **kwargs)[source]

Invalid use of arithmetic, such as dividing by zero.

exception py2neo.cypher.error.statement.ConstraintViolation(message, **kwargs)[source]

A constraint imposed by the statement is violated by the data in the database.

exception py2neo.cypher.error.statement.EntityNotFound(message, **kwargs)[source]

The statement is directly referring to an entity that does not exist.

exception py2neo.cypher.error.statement.InvalidArguments(message, **kwargs)[source]

The statement is attempting to perform operations using invalid arguments

exception py2neo.cypher.error.statement.InvalidSemantics(message, **kwargs)[source]

The statement is syntactically valid, but expresses something that the database cannot do.

exception py2neo.cypher.error.statement.InvalidSyntax(message, **kwargs)[source]

The statement contains invalid or unsupported syntax.

exception py2neo.cypher.error.statement.InvalidType(message, **kwargs)[source]

The statement is attempting to perform operations on values with types that are not supported by the operation.

exception py2neo.cypher.error.statement.NoSuchLabel(message, **kwargs)[source]

The statement is referring to a label that does not exist.

exception py2neo.cypher.error.statement.NoSuchProperty(message, **kwargs)[source]

The statement is referring to a property that does not exist.

exception py2neo.cypher.error.statement.ParameterMissing(message, **kwargs)[source]

The statement is referring to a parameter that was not provided in the request.

exception py2neo.cypher.error.transaction.ConcurrentRequest(message, **kwargs)[source]

There were concurrent requests accessing the same transaction, which is not allowed.

exception py2neo.cypher.error.transaction.EventHandlerThrewException(message, **kwargs)[source]

A transaction event handler threw an exception. The transaction will be rolled back.

exception py2neo.cypher.error.transaction.InvalidType(message, **kwargs)[source]

The transaction is of the wrong type to service the request. For instance, a transaction that has had schema modifications performed in it cannot be used to subsequently perform data operations, and vice versa.

exception py2neo.cypher.error.transaction.UnknownId(message, **kwargs)[source]

The request referred to a transaction that does not exist.

Database Errors

exception py2neo.cypher.DatabaseError(message, **kwargs)[source]

The database failed to service the request.

exception py2neo.cypher.error.schema.ConstraintCreationFailure(message, **kwargs)[source]

Creating a requested constraint failed.

exception py2neo.cypher.error.schema.ConstraintDropFailure(message, **kwargs)[source]

The database failed to drop a requested constraint.

exception py2neo.cypher.error.schema.IndexCreationFailure(message, **kwargs)[source]

Failed to create an index.

exception py2neo.cypher.error.schema.IndexDropFailure(message, **kwargs)[source]

The database failed to drop a requested index.

exception py2neo.cypher.error.schema.NoSuchLabel(message, **kwargs)[source]

The request accessed a label that did not exist.

exception py2neo.cypher.error.schema.NoSuchPropertyKey(message, **kwargs)[source]

The request accessed a property that does not exist.

exception py2neo.cypher.error.schema.NoSuchRelationshipType(message, **kwargs)[source]

The request accessed a relationship type that does not exist.

exception py2neo.cypher.error.schema.NoSuchSchemaRule(message, **kwargs)[source]

The request referred to a schema rule that does not exist.

exception py2neo.cypher.error.statement.ExecutionFailure(message, **kwargs)[source]

The database was unable to execute the statement.

exception py2neo.cypher.error.transaction.CouldNotBegin(message, **kwargs)[source]

The database was unable to start the transaction.

exception py2neo.cypher.error.transaction.CouldNotCommit(message, **kwargs)[source]

The database was unable to commit the transaction.

exception py2neo.cypher.error.transaction.CouldNotRollback(message, **kwargs)[source]

The database was unable to roll back the transaction.

exception py2neo.cypher.error.transaction.ReleaseLocksFailed(message, **kwargs)[source]

The transaction was unable to release one or more of its locks.

Transient Errors

exception py2neo.cypher.TransientError(message, **kwargs)[source]

The database cannot service the request right now, retrying later might yield a successful outcome.

exception py2neo.cypher.error.network.UnknownFailure(message, **kwargs)[source]

An unknown network failure occurred, a retry may resolve the issue.

exception py2neo.cypher.error.statement.ExternalResourceFailure(message, **kwargs)[source]

The external resource is not available

exception py2neo.cypher.error.transaction.AcquireLockTimeout(message, **kwargs)[source]

The transaction was unable to acquire a lock, for instance due to a timeout or the transaction thread being interrupted.

exception py2neo.cypher.error.transaction.DeadlockDetected(message, **kwargs)[source]

This transaction, and at least one more transaction, has acquired locks in a way that it will wait indefinitely, and the database has aborted it. Retrying this transaction will most likely be successful.

Command Line

Py2neo also provides a command line tool for executing Cypher queries, simply called cypher. To use this, pass the Cypher statement as a string argument:

$ cypher "CREATE (a:Person {name:'Alice'}) RETURN a"
   | a
---+------------------------------
 1 | (n1:Person {name:"Alice"})

Parameters can be supplied as command line options:

$ cypher -p name Bob "CREATE (a:Person {name:{name}}) RETURN a"
   | a
---+------------------------------
 1 | (n2:Person {name:"Bob"})

Alternatively, to pass multiple sets of parameters, a separate parameter file can be used:

$ cypher -f params.csv "CREATE (a:Person {name:{name},age:{age}}) RETURN a.name, a.age"
   | a.name | a.age
---+--------+-------
 1 | Carol  |    55

   | a.name | a.age
---+--------+-------
 1 | Dave   |    66

   | a.name | a.age
---+--------+-------
 1 | Ethel  |    77

   | a.name | a.age
---+--------+-------
 1 | Frank  |    88

The parameter file must be in CSV format with each value encoded as JSON. String values must therefore be enclosed in double quotes. For the example above, the file would look like this:

name,age
"Carol",55
"Dave",66
"Ethel",77
"Frank",88

By default, statements will be executed against the server at http://localhost:7474/db/data/. To change the database used, set the NEO4J_URI environment variable prior to execution.

As well as plain text, there are several other formats available for query output. The full list of formats is below.

  • Comma-separated values (-c, --csv)
  • Geoff (-g, --geoff)
  • Human-readable text (-h, --human)
  • JSON (-j, --json)
  • Tab-separated values (-t, --tsv)