Skip to content

Instantly share code, notes, and snippets.

@ikwattro
Created September 22, 2020 19:33
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 ikwattro/19747c9a6e1a7b2a1627c26bbf1bce9b to your computer and use it in GitHub Desktop.
Save ikwattro/19747c9a6e1a7b2a1627c26bbf1bce9b to your computer and use it in GitHub Desktop.
Hume Schema Generator
from neo4j import GraphDatabase
import json
import random
uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "neo4j"))
session = driver.session()
q = "CALL db.schema.visualization()"
result = list(session.run(q))
record = result[0]
classes = {}
relationships = {}
types_dict = {'String': 'STRING', 'Long': 'NUMBER', 'Date': 'DATE', 'Point': 'STRING'}
def to_hume_type(t):
return types_dict[t]
def canvas_position():
return {'x': random.randint(100, 1200), 'y': random.randint(50, 800)}
for node in record['nodes']:
classes[node['name']] = {
'label': node['name'],
'primaryKey': False,
'searchable': False,
'canvasPosition': canvas_position(),
'icon': 'mdi-circle-outline',
'color': '#aaa'
}
for rel in record['relationships']:
nodeFrom = rel.nodes[0]
nodeTo = rel.nodes[1]
relationships[rel.type] = {
'startId': nodeFrom.id,
'startLabel': nodeFrom['name'],
'endLabel': nodeTo['name'],
'endId': nodeTo.id,
'label': rel.type
}
q2 = "CALL db.schema.nodeTypeProperties()"
records = list(session.run(q2))
attributes_map = {}
for record in records:
labels = record['nodeLabels']
propertyName = record['propertyName']
propertyTypes = record['propertyTypes']
if (len(labels) == 1):
pType = to_hume_type(propertyTypes[0])
attributes_map.setdefault(labels[0], {'attributes': []})['attributes'].append({'label': propertyName, 'type': pType})
for (key, value) in attributes_map.items():
classes[key]['attributes'] = list(value['attributes'])
schema = {'classes': list(classes.values()), 'relationships': list(relationships.values())}
with open('schema-generated.json', 'w') as fp:
json.dump(schema, fp)
@ikwattro
Copy link
Author

Limitations :

  • No support for multi labels
  • No support for relationship properties

Note that the available Neo4j procedures do not offer the ability to infer a schema completely when relationship triple patterns are not unique across the schema.

For example :

(:Document)-[:MENTIONS]->(Person)-[:MENTIONS]->(Person)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment