Further query mechanisms

Auto-commit transactions

This is the most basic and limited form with which to run a Cypher query. The driver will not automatically retry auto-commit transactions, as it does instead for queries run with managed transactions.

You run an auto-commit transaction with the method Session.run(). It returns a Result object that needs to be processed with the related methods.

with driver.session() as session:
    session.run("CREATE (a:Person {name: $name})", name=name)

An auto-commit transaction gets committed at the latest when the session is destroyed, or before another transaction is executed within the same session. Other than that, there is no clear guarantee on when exactly an auto-commit transaction will be committed during the lifetime of a session. To ensure an auto-commit transaction is committed, you can call the .consume() method on its result.

Auto-commit transactions should only be used when transaction functions do not fit the purpose, or for quick prototyping.

This method is the only one that can be used for CALL {} IN TRANSACTIONS and PERIODIC COMMIT queries.

Configure auto-commit transactions with the Query object

The Query object allows to specify a query timeout and to attach metadata to the transaction. The metadata is visible in the server logs (as described for the unit_of_work decorator).

from neo4j import Query

with driver.session() as session:
    query = Query("CREATE (a:Person {name: $name})",
                  timeout=1.0,
                  metadata={"app_name": "people"})
    result = session.run(query, name=name)

Dynamic values in property keys, relationship types, and labels

In general, you should not concatenate parameters directly into a query, but rather use query parameters. There can however be circumstances where your query structure prevents the usage of parameters in all its parts. In fact, although parameters can be used for literals and expressions as well as node and relationship ids, they cannot be used for the following constructs:

  • property keys, so MATCH (n) WHERE n.$param = 'something' is invalid;

  • relationship types, so MATCH (n)-[:$param]→(m) is invalid;

  • labels, so MATCH (n:$param) is invalid.

For those queries, you are forced to use string concatenation. To protect against Cypher injections you should enclose the dynamic values in backticks and escape them yourself. Notice that Cypher processes Unicode, so take care of the Unicode literal \u0060 as well.

Manually escaping dynamic labels before concatenation.
label = "Person"
# convert \u0060 to literal backtick and then escape backticks
escaped_label = label.replace("\\u0060", "`").replace("`", "``")

with driver.session(database="neo4j") as session:
    session.run(
        f"MATCH (p:`{escaped_label}` {{name: $name}}) RETURN p.name",
        name="Alice",
    )

Another workaround, which avoids string concatenation, is using the APOC procedure apoc.merge.node. It supports dynamic labels and property keys, but only for node insertion.

Using apoc.merge.node to create a node with dynamic labels/property keys.
property_key = "name"
label = "Person"

with driver.session(database="neo4j") as session:
    session.run(
        "CALL apoc.merge.node($labels, $properties)",
        labels=[label], properties={property_key: "Alice"},
    )
If you are running Neo4j in Docker, APOC needs to be enabled when starting the container. See APOC - Installation - Docker.

Logging

The driver logs messages through the native logging library to a logger named neo4j. To redirect log messages to standard output, use the watch function:

import sys
from neo4j.debug import watch

watch("neo4j", out=sys.stdout)

Glossary

LTS

A Long Term Support release is one guaranteed to be supported for a number of years. Neo4j 4.4 is LTS, and Neo4j 5 will also have an LTS version.

Aura

Aura is Neo4j’s fully managed cloud service. It comes with both free and paid plans.

Driver

A Driver object holds the details required to establish connections with a Neo4j database. Every Neo4j-backed application requires a Driver object.

Cypher

Cypher is Neo4j’s graph query language that lets you retrieve data from the graph. It is like SQL, but for graphs.

APOC

Awesome Procedures On Cypher (APOC) is a library of (many) functions that can not be easily expressed in Cypher itself.

Bolt

Bolt is the protocol used for interaction between Neo4j instances and drivers. It listens on port 7687 by default.

ACID

Atomicity, Consistency, Isolation, Durability (ACID) are properties guaranteeing that database transactions are processed reliably. An ACID-compliant DBMS ensures that the data in the database remains accurate and consistent despite failures.

eventual consistency

A database is eventually consistent if it provides the guarantee that all cluster members will, at some point in time, store the latest version of the data.

causal consistency

A database is causally consistent if read and write queries are seen by every member of the cluster in the same order. This is stronger than eventual consistency.

null

The null marker is not a type but a placeholder for absence of value. For more information, see Cypher Manual — Working with null.

transaction

A transaction is a unit of work that is either committed in its entirety or rolled back on failure. An example is a bank transfer: it involves multiple steps, but they must all succeed or be reverted, to avoid money being subtracted from one account but not added to the other.