Databases 16 min read

Using Neo4j Graph Database with Py2neo: Nodes, Relationships, Subgraphs, Walkable, and OGM

This article provides a comprehensive guide to Neo4j, an open‑source graph database, covering its data model, key features, installation, and detailed Python usage with the Py2neo library, including node and relationship creation, property handling, subgraph operations, walkable traversals, and object‑graph mapping (OGM).

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Using Neo4j Graph Database with Py2neo: Nodes, Relationships, Subgraphs, Walkable, and OGM

Neo4j is a leading open‑source graph database written in Java, where data is stored as nodes, relationships, and properties rather than tables. Nodes can have multiple labels, relationships have a type, and both can hold arbitrary properties stored as key‑value pairs.

Key features of Neo4j include a simple query language (CQL), ACID compliance, native graph processing engine, indexing via Apache Lucene, support for UNIQUE constraints, and a browser UI for executing CQL commands.

Installation can be done by downloading the installer from the official website.

Py2Neo Usage

Py2Neo is a Python library for interacting with Neo4j.

Installation

pip3 install py2neo

Node & Relationship

from py2neo import Node, Relationship

a = Node('Person', name='Alice')
b = Node('Person', name='Bob')
r = Relationship(a, 'KNOWS', b)
print(a, b, r)

Result shows two nodes and a relationship between them.

Property Assignment

a['age'] = 20
b['age'] = 21
r['time'] = '2017/08/31'
print(a, b, r)

Properties can be set like a dictionary; they are stored as basic types or arrays.

Default Property with setdefault()

a.setdefault('location', '北京')
print(a)

Batch Update with update()

data = {
    'name': 'Amy',
    'age': 21
}
a.update(data)
print(a)

Subgraph

A subgraph is a collection of nodes and relationships.

from py2neo import Node, Relationship

a = Node('Person', name='Alice')
b = Node('Person', name='Bob')
r = Relationship(a, 'KNOWS', b)
s = a | b | r
print(s)

Methods nodes() and relationships() retrieve the components.

print(s.nodes())
print(s.relationships())

Subgraph Intersection

s1 = a | b | r
s2 = a | b
print(s1 & s2)

Size and Order

from py2neo import Node, Relationship, size, order
s = a | b | r
print(order(s))
print(size(s))

Walkable

A walkable adds traversal information to a subgraph.

from py2neo import Node, Relationship

a = Node('Person', name='Alice')
b = Node('Person', name='Bob')
c = Node('Person', name='Mike')
ab = Relationship(a, "KNOWS", b)
ac = Relationship(a, "KNOWS", c)
w = ab + Relationship(b, "LIKES", c) + ac
print(w)

Traverse the walkable:

from py2neo import walk
for item in walk(w):
    print(item)

Graph API

The Graph class represents a Neo4j database and provides methods for CRUD operations.

from py2neo import Graph
graph_1 = Graph()
graph_2 = Graph(host="localhost")
graph_3 = Graph("http://localhost:7474/db/data/")

Create a subgraph in the database:

from py2neo import Node, Relationship, Graph

a = Node('Person', name='Alice')
b = Node('Person', name='Bob')
r = Relationship(a, 'KNOWS', b)
s = a | b | r
graph = Graph(password='123456')
graph.create(s)

Run a CQL query and get results as a list or DataFrame:

from py2neo import Graph

graph = Graph(password='123456')
data = graph.data('MATCH (p:Person) RETURN p')
print(data)
from py2neo import Graph
from pandas import DataFrame

graph = Graph(password='123456')
data = graph.data('MATCH (p:Person) RETURN p')
df = DataFrame(data)
print(df)

NodeSelector

For more flexible queries, use NodeSelector .

from py2neo import Graph, NodeSelector

graph = Graph(password='123456')
selector = NodeSelector(graph)
persons = selector.select('Person', age=21)
print(list(persons))

Regex filtering:

persons = selector.select('Person').where('_.name =~ "A.*"')
print(list(persons))

Sorting:

persons = selector.select('Person').order_by('_.age')
print(list(persons))

Get first match:

person = selector.select('Person').where('_.name =~ "A.*"').first()
print(person)

Object‑Graph Mapping (OGM)

OGM provides an ORM‑like interface for Neo4j.

from py2neo.ogm import GraphObject, Property, RelatedTo, RelatedFrom

class Movie(GraphObject):
    __primarykey__ = 'title'
    title = Property()
    released = Property()
    actors = RelatedFrom('Person', 'ACTED_IN')
    directors = RelatedFrom('Person', 'DIRECTED')
    producers = RelatedFrom('Person', 'PRODUCED')

class Person(GraphObject):
    __primarykey__ = 'name'
    name = Property()
    born = Property()
    acted_in = RelatedTo('Movie')
    directed = RelatedTo('Movie')
    produced = RelatedTo('Movie')

Query a person and access attributes:

graph = Graph(password='123456')
person = Person.select(graph).where(age=21).first()
print(person)
print(person.name)
print(person.age)

Update a property and push to the database:

print(person.__ogm__.node)
person.age = 22
print(person.__ogm__.node)
graph.push(person)

Add a relationship via OGM:

print(list(person.knows))
new_person = Person()
new_person.name = 'Durant'
new_person.age = 28
person.knows.add(new_person)
print(list(person.knows))

Remove a relationship and delete a node:

person = Person.select(graph).where(name='Alice').first()
target = Person.select(graph).where(name='Durant').first()
person.knows.remove(target)
graph.push(person)
graph.delete(target)

These examples demonstrate how to model, query, and modify graph data in Neo4j using Python.

pythongraph databaseNeo4jCQLOGMPy2neo
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.