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).
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 py2neoNode & 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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.