@@ -60,8 +60,8 @@ class DiGraph(Graph, nx.DiGraph):
6060 name : str (optional, default: None)
6161 Name of the graph in the database. If the graph already exists,
6262 the user can pass the name of the graph to connect to it. If
63- the graph does not exist, the user can create a new graph by
64- passing the name. NOTE: Must be used in conjunction with
63+ the graph does not exist, a General Graph will be created by
64+ passing the ** name** . NOTE: Must be used in conjunction with
6565 **incoming_graph_data** if the user wants to persist the graph
6666 in ArangoDB.
6767
@@ -125,6 +125,12 @@ class DiGraph(Graph, nx.DiGraph):
125125 whenever possible. NOTE: This feature is experimental and may not work
126126 as expected.
127127
128+ overwrite_graph : bool (optional, default: False)
129+ Whether to overwrite the graph in the database if it already exists. If
130+ set to True, the graph collections will be dropped and recreated. Note that
131+ this operation is irreversible and will result in the loss of all data in
132+ the graph. NOTE: If set to True, Collection Indexes will also be lost.
133+
128134 args: positional arguments for nx.Graph
129135 Additional arguments passed to nx.Graph.
130136
@@ -154,6 +160,7 @@ def __init__(
154160 write_async : bool = True ,
155161 symmetrize_edges : bool = False ,
156162 use_arango_views : bool = False ,
163+ overwrite_graph : bool = False ,
157164 * args : Any ,
158165 ** kwargs : Any ,
159166 ):
@@ -171,13 +178,15 @@ def __init__(
171178 write_async ,
172179 symmetrize_edges ,
173180 use_arango_views ,
181+ overwrite_graph ,
174182 * args ,
175183 ** kwargs ,
176184 )
177185
178186 if self .graph_exists_in_db :
179187 self .clear_edges = self .clear_edges_override
180188 self .add_node = self .add_node_override
189+ self .add_nodes_from = self .add_nodes_from_override
181190 self .remove_node = self .remove_node_override
182191 self .reverse = self .reverse_override
183192
@@ -194,6 +203,7 @@ def __init__(
194203 and not self ._loaded_incoming_graph_data
195204 ):
196205 nx .convert .to_networkx_graph (incoming_graph_data , create_using = self )
206+ self ._loaded_incoming_graph_data = True
197207
198208 #######################
199209 # nx.DiGraph Overides #
@@ -225,9 +235,10 @@ def clear_edges_override(self):
225235 super ().clear_edges ()
226236
227237 def add_node_override (self , node_for_adding , ** attr ):
238+ if node_for_adding is None :
239+ raise ValueError ("None cannot be a node" )
240+
228241 if node_for_adding not in self ._succ :
229- if node_for_adding is None :
230- raise ValueError ("None cannot be a node" )
231242
232243 self ._succ [node_for_adding ] = self .adjlist_inner_dict_factory ()
233244 self ._pred [node_for_adding ] = self .adjlist_inner_dict_factory ()
@@ -241,12 +252,15 @@ def add_node_override(self, node_for_adding, **attr):
241252 # attr_dict.update(attr)
242253
243254 # New:
244- self ._node [node_for_adding ] = self .node_attr_dict_factory ()
245- self ._node [node_for_adding ].update (attr )
255+ node_attr_dict = self .node_attr_dict_factory ()
256+ node_attr_dict .data = attr
257+ self ._node [node_for_adding ] = node_attr_dict
246258
247259 # Reason:
248- # Invoking `update` on the `attr_dict` without `attr_dict.node_id` being set
249- # i.e trying to update a node's attributes before we know _which_ node it is
260+ # We can optimize the process of adding a node by creating avoiding
261+ # the creation of a new dictionary and updating it with the attributes.
262+ # Instead, we can create a new node_attr_dict object and set the attributes
263+ # directly. This only makes 1 network call to the database instead of 2.
250264
251265 ###########################
252266
@@ -255,6 +269,49 @@ def add_node_override(self, node_for_adding, **attr):
255269
256270 nx ._clear_cache (self )
257271
272+ def add_nodes_from_override (self , nodes_for_adding , ** attr ):
273+ for n in nodes_for_adding :
274+ try :
275+ newnode = n not in self ._node
276+ newdict = attr
277+ except TypeError :
278+ n , ndict = n
279+ newnode = n not in self ._node
280+ newdict = attr .copy ()
281+ newdict .update (ndict )
282+ if newnode :
283+ if n is None :
284+ raise ValueError ("None cannot be a node" )
285+ self ._succ [n ] = self .adjlist_inner_dict_factory ()
286+ self ._pred [n ] = self .adjlist_inner_dict_factory ()
287+
288+ ######################
289+ # NOTE: monkey patch #
290+ ######################
291+
292+ # Old:
293+ # self._node[n] = self.node_attr_dict_factory()
294+ #
295+ # self._node[n].update(newdict)
296+
297+ # New:
298+ node_attr_dict = self .node_attr_dict_factory ()
299+ node_attr_dict .data = newdict
300+ self ._node [n ] = node_attr_dict
301+
302+ else :
303+ self ._node [n ].update (newdict )
304+
305+ # Reason:
306+ # We can optimize the process of adding a node by creating avoiding
307+ # the creation of a new dictionary and updating it with the attributes.
308+ # Instead, we create a new node_attr_dict object and set the attributes
309+ # directly. This only makes 1 network call to the database instead of 2.
310+
311+ ###########################
312+
313+ nx ._clear_cache (self )
314+
258315 def remove_node_override (self , n ):
259316 if isinstance (n , (str , int )):
260317 n = get_node_id (str (n ), self .default_node_type )
0 commit comments