7
7
from linkml_store .api import Collection
8
8
from linkml_store .api .collection import DEFAULT_FACET_LIMIT , OBJECT
9
9
from linkml_store .api .queries import Query , QueryResult
10
- from linkml_store .graphs .graph_map import GraphProjection , EdgeProjection , NodeProjection
10
+ from linkml_store .graphs .graph_map import EdgeProjection , GraphProjection , NodeProjection
11
11
12
12
logger = logging .getLogger (__name__ )
13
13
@@ -35,7 +35,7 @@ def session(self) -> Session:
35
35
36
36
def _check_if_initialized (self ) -> bool :
37
37
with self .session () as session :
38
- result = session .run (f "MATCH (n) RETURN count(n) > 0 as exists" )
38
+ result = session .run ("MATCH (n) RETURN count(n) > 0 as exists" )
39
39
return result .single ()["exists" ]
40
40
41
41
@property
@@ -101,7 +101,9 @@ def set_is_node_collection(self, force=False):
101
101
raise ValueError ("Cannot reassign without force=True" )
102
102
self .metadata .graph_projection = NodeProjection ()
103
103
104
- def _prop_clause (self , obj : OBJECT , node_var : Optional [str ] = None , exclude_attributes : Optional [List [str ]]= None ) -> str :
104
+ def _prop_clause (
105
+ self , obj : OBJECT , node_var : Optional [str ] = None , exclude_attributes : Optional [List [str ]] = None
106
+ ) -> str :
105
107
if exclude_attributes is None :
106
108
exclude_attributes = [self .category_labels_attribute ]
107
109
node_prefix = node_var + "." if node_var else ""
@@ -141,7 +143,9 @@ def _create_insert_cypher_query(self, obj: OBJECT) -> str:
141
143
# check if nodes present; if not, make dangling stubs
142
144
# TODO: decide on how this should be handled in validation if some fields are required
143
145
for node_id in [obj [ep .subject_attribute ], obj [ep .object_attribute ]]:
144
- check_query = f"MATCH (n {{{ ep .identifier_attribute } : ${ ep .identifier_attribute } }}) RETURN count(n) as count"
146
+ check_query = (
147
+ f"MATCH (n {{{ ep .identifier_attribute } : ${ ep .identifier_attribute } }}) RETURN count(n) as count"
148
+ )
145
149
with self .session () as session :
146
150
result = session .run (check_query , ** {ep .identifier_attribute : node_id })
147
151
if result .single ()["count" ] == 0 :
@@ -150,11 +154,9 @@ def _create_insert_cypher_query(self, obj: OBJECT) -> str:
150
154
session .run (stub_query , ** {ep .identifier_attribute : node_id })
151
155
else :
152
156
raise ValueError (f"Node with identifier { node_id } not found in the database." )
153
- edge_props = self ._prop_clause (obj , exclude_attributes = [
154
- ep .subject_attribute ,
155
- ep .predicate_attribute ,
156
- ep .object_attribute
157
- ])
157
+ edge_props = self ._prop_clause (
158
+ obj , exclude_attributes = [ep .subject_attribute , ep .predicate_attribute , ep .object_attribute ]
159
+ )
158
160
return f"""
159
161
MATCH (s {{{ id_attribute } : ${ ep .subject_attribute } }}), (o {{{ id_attribute } : ${ ep .object_attribute } }})
160
162
CREATE (s)-[r:{ pred } {{{ edge_props } }}]->(o)
@@ -175,13 +177,15 @@ def query(self, query: Query, limit: Optional[int] = None, offset: Optional[int]
175
177
if self .is_edge_collection :
176
178
rows = [self ._edge_to_dict (record ) for record in result ]
177
179
else :
180
+
178
181
def node_to_dict (n ) -> dict :
179
182
d = dict (n .items ())
180
183
if ca :
181
184
labels = list (n .labels )
182
185
if labels :
183
186
d [ca ] = labels [0 ]
184
187
return d
188
+
185
189
rows = [node_to_dict (record ["n" ]) for record in result ]
186
190
187
191
# count_query = self._build_count_query(query, is_count=True)
@@ -191,7 +195,9 @@ def node_to_dict(n) -> dict:
191
195
192
196
return QueryResult (query = query , num_rows = count , rows = rows )
193
197
194
- def _build_cypher_query (self , query : Query , limit : Optional [int ] = None , offset : Optional [int ]= None , is_count = False ) -> str :
198
+ def _build_cypher_query (
199
+ self , query : Query , limit : Optional [int ] = None , offset : Optional [int ] = None , is_count = False
200
+ ) -> str :
195
201
if self .is_edge_collection :
196
202
ep = self .edge_projection
197
203
ia = ep .identifier_attribute
@@ -247,8 +253,7 @@ def _build_cypher_query(self, query: Query, limit: Optional[int] = None, offset:
247
253
248
254
return cypher_query
249
255
250
-
251
- def _build_where_clause (self , where_clause : Dict [str , Any ], prefix : str = 'n' ) -> str :
256
+ def _build_where_clause (self , where_clause : Dict [str , Any ], prefix : str = "n" ) -> str :
252
257
conditions = []
253
258
if where_clause is None :
254
259
return ""
@@ -269,15 +274,15 @@ def _edge_to_dict(self, record: Dict) -> Dict[str, Any]:
269
274
ep .subject_attribute : record ["subject" ],
270
275
ep .predicate_attribute : record ["predicate" ],
271
276
ep .object_attribute : record ["object" ],
272
- ** dict (r .items ())
277
+ ** dict (r .items ()),
273
278
}
274
279
275
280
def query_facets (
276
- self ,
277
- where : Dict = None ,
278
- facet_columns : List [Union [str , Tuple [str , ...]]] = None ,
279
- facet_limit = DEFAULT_FACET_LIMIT ,
280
- ** kwargs ,
281
+ self ,
282
+ where : Dict = None ,
283
+ facet_columns : List [Union [str , Tuple [str , ...]]] = None ,
284
+ facet_limit = DEFAULT_FACET_LIMIT ,
285
+ ** kwargs ,
281
286
) -> Dict [Union [str , Tuple [str , ...]], List [Tuple [Any , int ]]]:
282
287
results = {}
283
288
if not facet_columns :
@@ -334,23 +339,24 @@ def delete(self, objs: Union[OBJECT, List[OBJECT]], **kwargs) -> int:
334
339
335
340
return deleted_nodes
336
341
337
- def delete_where (self , where : Optional [Dict [str , Any ]] = None ,
338
- missing_ok = True , ** kwargs ) -> int :
342
+ def delete_where (self , where : Optional [Dict [str , Any ]] = None , missing_ok = True , ** kwargs ) -> int :
339
343
delete_policy = self .delete_policy
340
344
where_clause = self ._build_where_clause (where ) if where else ""
341
345
node_pattern = self ._node_pattern (where )
342
346
343
347
with self .session () as session :
344
- deleted_nodes , deleted_relationships = self ._execute_delete (session , node_pattern , where_clause ,
345
- delete_policy )
348
+ deleted_nodes , deleted_relationships = self ._execute_delete (
349
+ session , node_pattern , where_clause , delete_policy
350
+ )
346
351
347
352
if deleted_nodes == 0 and not missing_ok :
348
353
raise ValueError (f"No nodes found for { where } " )
349
354
350
355
return deleted_nodes
351
356
352
- def _execute_delete (self , session , node_pattern : str , where_clause : str , delete_policy : DeletePolicy , ** params ) -> \
353
- Tuple [int , int ]:
357
+ def _execute_delete (
358
+ self , session , node_pattern : str , where_clause : str , delete_policy : DeletePolicy , ** params
359
+ ) -> Tuple [int , int ]:
354
360
deleted_relationships = 0
355
361
deleted_nodes = 0
356
362
@@ -376,7 +382,6 @@ def _execute_delete(self, session, node_pattern: str, where_clause: str, delete_
376
382
377
383
return deleted_nodes , deleted_relationships
378
384
379
-
380
385
def update (self , objs : Union [OBJECT , List [OBJECT ]], ** kwargs ) -> int :
381
386
if not isinstance (objs , list ):
382
387
objs = [objs ]
@@ -393,30 +398,32 @@ def update(self, objs: Union[OBJECT, List[OBJECT]], **kwargs) -> int:
393
398
def _create_update_cypher_query (self , obj : OBJECT ) -> str :
394
399
id_attribute = self .identifier_attribute
395
400
category_labels_attribute = self .category_labels_attribute
396
- node_pattern = self ._node_pattern (obj )
397
401
398
402
# Prepare SET clause
399
403
set_items = [f"n.{ k } = ${ k } " for k in obj .keys () if k not in [id_attribute , category_labels_attribute ]]
400
404
set_clause = ", " .join (set_items )
401
405
402
406
# Prepare labels update
403
407
labels_to_add = []
404
- labels_to_remove = []
408
+ # labels_to_remove = []
405
409
if category_labels_attribute in obj :
406
- new_labels = obj [category_labels_attribute ] if isinstance (obj [category_labels_attribute ], list ) else [
407
- obj [category_labels_attribute ]]
410
+ new_labels = (
411
+ obj [category_labels_attribute ]
412
+ if isinstance (obj [category_labels_attribute ], list )
413
+ else [obj [category_labels_attribute ]]
414
+ )
408
415
labels_to_add = [f":{ label } " for label in new_labels ]
409
- labels_to_remove = [f ":Label" for _ in new_labels ] # Placeholder for labels to remove
416
+ # labels_to_remove = [":Label" for _ in new_labels] # Placeholder for labels to remove
410
417
411
418
# Construct the query
412
419
query = f"MATCH (n {{{ id_attribute } : ${ id_attribute } }})\n "
413
- #if labels_to_remove:
420
+ # f labels_to_remove:
414
421
# query += f"REMOVE n{' '.join(labels_to_remove)}\n"
415
422
if labels_to_add :
416
423
query += f"SET n{ ' ' .join (labels_to_add )} \n "
417
- # f"REMOVE n{' '.join(labels_to_remove)}' if labels_to_remove else ''}"
418
- # f"{f'SET n{' '.join(labels_to_add)}' if labels_to_add else ''}"
424
+ # f"REMOVE n{' '.join(labels_to_remove)}' if labels_to_remove else ''}"
425
+ # f"{f'SET n{' '.join(labels_to_add)}' if labels_to_add else ''}"
419
426
query += f"SET { set_clause } \n "
420
427
query += "RETURN n"
421
428
print (query )
422
- return query
429
+ return query
0 commit comments