I am using pyArango Python package to create several Collections (documents (vertices) and edges). How can I programmatically create a graph using existing vertices and edges? I know how to create a graph using ArangoDB web interface "Add Graph" but that requires a tedious task because of a large number of Collections.
2 Answers
After inspect the network flow from the WebGui, I found out that Add graph essentially is sending a json post request with Edge
and Document
connection name as string input. Thus, what is prevent us using existing edges and documents is the validation built default in pyarango
def _checkCollectionList(lst):
for colName in lst:
if not COL.isCollection(colName):
raise ValueError("'%s' is not a defined Collection" % colName)
graphClass = GR.getGraphClass(name)
ed = []
for e in graphClass._edgeDefinitions:
if not COL.isEdgeCollection(e.edgesCollection):
raise ValueError("'%s' is not a defined Edge Collection" % e.edgesCollection)
_checkCollectionList(e.fromCollections)
_checkCollectionList(e.toCollections)
ed.append(e.toJson())
_checkCollectionList(graphClass._orphanedCollections)
To overcome this issue, we only need to implement class first before create graph. for e.g., I have two documents collections people and department, and I want to create a graph which:
- people -> knowns -> people
- people -> belongs_to -> department
suppose I already have collection "people", "department", "knowns", "belongs_to" in my arangodb, the code to create a graph is as following:
from pyArango.collection import Collection, Field
from pyArango.graph import Graph, EdgeDefinition
class knowns(Edges):
pass
class belongs_to(Edges):
pass
class people(Collection):
pass
class department(Collection):
pass
# Here's how you define a graph
class MyGraph(Graph) :
_edgeDefinitions = [EdgeDefinition('knowns', ['people'], ['people']),
EdgeDefinition('belongs_to', ['people'], ['department'])]
_orphanedCollections = []
theGraph = arrango_db.createGraph(name="MyGraph", createCollections=False)
Be aware that the class name is exactly the same as the string I passed into graph creation. Now we have the graph created in ArangoDB:
Another solution, useful when you already have defined Nodes and Edges, is to dynamically create the classes with type
:
from pyArango.graph import Graph, EdgeDefinition
from pyArango.collection import Collection, Edges
# generate the class for "knowns", inheriting class "Edges", etc.
_ = type("knowns", (Edges,), {})
_ = type("belongs_to", (Edges,), {})
_ = type("people", (Collection,), {})
_ = type("department", (Collection,), {})
# finally generate the class for the graph
_ = type(attribute+'Graph', (Graph,),
{"_edgeDefinitions" : [EdgeDefinition('knowns', ['people'], ['people']),
EdgeDefinition('belongs_to', ['people'], ['department'])],
"_orphanedCollections" : []})
db.createGraph(name=MyGraph, createCollections=False)