Skip to content

Instantly share code, notes, and snippets.

@gregroberts
Last active January 3, 2018 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gregroberts/0211ae63b647cf826b18 to your computer and use it in GitHub Desktop.
Save gregroberts/0211ae63b647cf826b18 to your computer and use it in GitHub Desktop.
Py2neo Write a report on the contents of a graph database, describe what nodes are in, what sort of properties they (seem to) have, and what edges come in and out of each
import py2neo
import datetime
#where we write it
f_name = 'DBREPORT_%s.txt' % datetime.datetime.today().strftime('%Y-%m-%d')
#overwrite anything previous
with open(f_name,'wb') as f:
f.write('REPORT COMPILATION STARTED AT %s' % datetime.datetime.now())
def doline(line):
'''writes a line, also prints it'''
l = ''.join(line)
with open(f_name,'ab+') as f:
f.write(l)
print l
def describe_nodeset(labels, graph):
'''yields lines to describe stuff on a particular set of nodes'''
labs = ':'.join(labels)
props = graph.cypher.execute('MATCH (n:%s) return n limit 1' % labs)[0].n.properties
yield 'Arbitrary Node has properties:'
for i,j in props.items():
#truncate for readiblity
if len(`j`) > 20:
yield '\t',`i`,':',`j`[:20]
else:
yield '\t',`i`,':',`j`
edges = graph.cypher.execute('''MATCH (n:%s)
OPTIONAL MATCH (n)-[r]->(m)
RETURN
type(r) as type,
labels(m) as target,
count(distinct r) as count
'''% labs)
yield 'Nodeset has outbound edges:'
yield '\t|edgetype|target_labset|count(rels)'
for i in edges:
if i.count > 0:
yield '\t',`i.type`, '|',`':'.join(list(i.target or ['NO LABELS']))`, '|',`i.count`
edges = graph.cypher.execute('''MATCH (n:%s)
OPTIONAL MATCH (n)<-[r]-(m)
RETURN
type(r) as type,
labels(m) as target,
count(distinct r) as count
'''% labs)
yield 'Nodeset has inbound edges:'
yield '\t|edgetype|source_labset|count(rels)'
for i in edges:
if i.count > 0:
yield '\t',`i.type`, '|',`':'.join(list(i.target or ['NO LABELS']))`, '|',`i.count`
def report_nodes(graph):
'''we identify sets of nodes as having the same SET of labels
for each such set, we give some basic stats about these things
within your graph'''
nodes = graph.cypher.execute('MATCH (n) return labels(n) as labset, count(distinct n) as count')
for i in nodes:
yield 'Labels: %s, count %d' % (':'.join(i.labset or ['NO LABELS']), i.count)
for line in describe_nodeset(i.labset, graph):
yield line
def write_report(graph):
doline('WRITING REPORT FOR DATABASE %s' % graph.uri)
for i in report_nodes(graph):
doline(i)
if __name__ == '__main__':
#usage:
# python database_report.py local
#-will produce and print out a full report
#-on the database specified at graphs['local']
#
#or do a report on a different graph by providing the uri to that graph
#as an argument:
# python database_report.py http://neo4j:neo4j@localhost:7474/db/data/
graphs = {
'local':'http://neo4j:neo4j@localhost:7474/db/data/',
'live':'https://<USERNAME>:<PASSWORD>@<DB_URL>/db/data',
}
#populate graphs with a set of neos you care about
from sys import argv
graph = py2neo.Graph(graphs.get(argv[1], argv[1]))
write_report(graph)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment