|
| 1 | +import neo4j |
1 | 2 | from neo4j.exceptions import TransactionError |
2 | | -from schema.schema_constants import SchemaConstants |
| 3 | +from neo4j import Session as Neo4jSession |
| 4 | +from schema.schema_constants import SchemaConstants, Neo4jRelationshipEnum |
3 | 5 | import logging |
4 | 6 |
|
5 | 7 | logger = logging.getLogger(__name__) |
6 | 8 |
|
7 | 9 | # The filed name of the single result record |
8 | 10 | record_field_name = 'result' |
9 | 11 |
|
10 | | - |
11 | 12 | #################################################################################################### |
12 | 13 | ## Functions can be called by app.py, schema_manager.py, and schema_triggers.py |
13 | 14 | #################################################################################################### |
@@ -109,7 +110,38 @@ def get_entity(neo4j_driver, uuid): |
109 | 110 |
|
110 | 111 | return result |
111 | 112 |
|
| 113 | +""" |
| 114 | +Given a list of UUIDs, return a dict mapping uuid -> entity_node |
| 115 | +Only UUIDs present in Neo4j will be returned. |
112 | 116 |
|
| 117 | +Parameters |
| 118 | +---------- |
| 119 | +neo4j_driver : neo4j.Driver object |
| 120 | + The neo4j database connection pool |
| 121 | +uuid_list : list of str |
| 122 | + The uuids of target entities to retrieve from Neo4j |
| 123 | +
|
| 124 | +Returns |
| 125 | +------- |
| 126 | +dict |
| 127 | + A dictionary of entity details returned from the Cypher query, keyed by |
| 128 | + the uuid provided in uuid_list. |
| 129 | +""" |
| 130 | +def identify_existing_dataset_entities(neo4j_driver, dataset_uuid_list:list): |
| 131 | + |
| 132 | + if not dataset_uuid_list: |
| 133 | + return {} |
| 134 | + |
| 135 | + query = """ |
| 136 | + MATCH (e:Entity) |
| 137 | + WHERE e.uuid IN $param_uuids |
| 138 | + AND e.entity_type='Dataset' |
| 139 | + RETURN e.uuid AS uuid |
| 140 | + """ |
| 141 | + |
| 142 | + with neo4j_driver.session() as session: |
| 143 | + results = session.run(query, param_uuids=dataset_uuid_list) |
| 144 | + return [record["uuid"] for record in results] |
113 | 145 |
|
114 | 146 | """ |
115 | 147 | Get the uuids for each entity in a list that doesn't belong to a certain entity type. Uuids are ordered by type |
@@ -889,13 +921,11 @@ def link_collection_to_datasets(neo4j_driver, collection_uuid, dataset_uuid_list |
889 | 921 | _delete_collection_linkages_tx(tx=tx |
890 | 922 | , uuid=collection_uuid) |
891 | 923 |
|
892 | | - # Create relationship from each member Dataset node to this Collection node |
893 | | - for dataset_uuid in dataset_uuid_list: |
894 | | - create_relationship_tx(tx=tx |
895 | | - , source_node_uuid=dataset_uuid |
896 | | - , direction='->' |
897 | | - , target_node_uuid=collection_uuid |
898 | | - , relationship='IN_COLLECTION') |
| 924 | + _create_relationships_unwind_tx(tx=tx |
| 925 | + , source_uuid_list=dataset_uuid_list |
| 926 | + , target_uuid=collection_uuid |
| 927 | + , relationship=Neo4jRelationshipEnum.IN_COLLECTION |
| 928 | + , direction='->') |
899 | 929 |
|
900 | 930 | tx.commit() |
901 | 931 | except TransactionError as te: |
@@ -1980,6 +2010,43 @@ def create_relationship_tx(tx, source_node_uuid, target_node_uuid, relationship, |
1980 | 2010 |
|
1981 | 2011 | result = tx.run(query) |
1982 | 2012 |
|
| 2013 | +""" |
| 2014 | +Create multiple relationships between a target node and each node in |
| 2015 | +a list of source nodes in neo4j |
| 2016 | +
|
| 2017 | +Parameters |
| 2018 | +---------- |
| 2019 | +tx : neo4j.Session object |
| 2020 | + The neo4j.Session object instance |
| 2021 | +source_uuid_list : list[str] |
| 2022 | + A list of UUIDs for nodes which will have a relationship to the node with target_uuid |
| 2023 | +target_uuid : str |
| 2024 | + The UUID of target node |
| 2025 | +relationship : Neo4jRelationshipEnum |
| 2026 | + The string for the Neo4j relationship type between each source node and the target node. |
| 2027 | +direction: str |
| 2028 | + The relationship direction of each source node to the target node: outgoing `->` or incoming `<-` |
| 2029 | + Neo4j CQL CREATE command supports only directional relationships |
| 2030 | +""" |
| 2031 | +def _create_relationships_unwind_tx(tx:Neo4jSession, source_uuid_list:list, target_uuid:str |
| 2032 | + , relationship:Neo4jRelationshipEnum, direction:str)->None: |
| 2033 | + logger.info("====== enter _create_relationships_unwind_tx() ======") |
| 2034 | + incoming = direction if direction == "<-" else "-" |
| 2035 | + outgoing = direction if direction == "->" else "-" |
| 2036 | + |
| 2037 | + query = ( |
| 2038 | + f"MATCH (t {{uuid: $target_uuid}}) " |
| 2039 | + f"UNWIND $source_uuid_list AS src_uuid " |
| 2040 | + f"MATCH (s {{uuid: src_uuid}}) " |
| 2041 | + f"CREATE (s){incoming}[r:{relationship.value}]{outgoing}(t) " |
| 2042 | + f"RETURN src_uuid AS linked_uuid" |
| 2043 | + ) |
| 2044 | + |
| 2045 | + result = tx.run( query=query |
| 2046 | + , target_uuid=target_uuid |
| 2047 | + , source_uuid_list=source_uuid_list) |
| 2048 | + logger.info("====== returning from _create_relationships_unwind_tx() ======") |
| 2049 | + |
1983 | 2050 | """ |
1984 | 2051 | Execute one query to create all outgoing relationships from each node whose |
1985 | 2052 | identifier is in the source node list to the target Activity node in neo4j |
|
0 commit comments