Last active
January 3, 2018 15:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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