Skip to content

Commit ac13aef

Browse files
authored
Merge pull request #122 from adamnsch/allow-string-label-in-construct
Allow string label in community `construct`
2 parents 45e09e7 + f4c86ee commit ac13aef

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,21 @@ To do this we provide the `gds.alpha.graph.construct` method with node data fram
8989

9090
```python
9191
nodes = pandas.DataFrame(
92-
"nodeId": [0, 1, 2, 3],
93-
"labels": ["A", "B", "C", "A"],
94-
"prop1": [42, 1337, 8, 0],
95-
"otherProperty": [0.1, 0.2, 0.3, 0.4]
92+
{
93+
"nodeId": [0, 1, 2, 3],
94+
"labels": ["A", "B", "C", "A"],
95+
"prop1": [42, 1337, 8, 0],
96+
"otherProperty": [0.1, 0.2, 0.3, 0.4]
97+
}
9698
)
9799

98100
relationships = pandas.DataFrame(
99-
"sourceId": [0, 1, 2, 3],
100-
"targetId": [1, 2, 3, 0],
101-
"relationshipType": ["REL", "REL", "REL", "REL"],
102-
"weight": [0.0, 0.0, 0.1, 42.0]
101+
{
102+
"sourceNodeId": [0, 1, 2, 3],
103+
"targetNodeId": [1, 2, 3, 0],
104+
"relationshipType": ["REL", "REL", "REL", "REL"],
105+
"weight": [0.0, 0.0, 0.1, 42.0]
106+
}
103107
)
104108

105109
G = gds.alpha.graph.construct(

graphdatascience/query_runner/cypher_graph_constructor.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import warnings
2-
from typing import List, Set
2+
from typing import Any, List, Set, Tuple
33

44
from pandas.core.frame import DataFrame
55

@@ -40,15 +40,18 @@ def run(self, node_dfs: List[DataFrame], relationship_dfs: List[DataFrame]) -> N
4040
"{readConcurrency: $read_concurrency, parameters: { nodes: $nodes, relationships: $relationships }})"
4141
)
4242

43+
node_query, nodes = self._node_query(node_dfs[0])
44+
relationship_query, relationships = self._relationship_query(relationship_dfs[0])
45+
4346
self._query_runner.run_query(
4447
query,
4548
{
4649
"graph_name": self._graph_name,
47-
"node_query": self._node_query(node_dfs[0]),
48-
"relationship_query": self._relationship_query(relationship_dfs[0]),
50+
"node_query": node_query,
51+
"relationship_query": relationship_query,
4952
"read_concurrency": self._concurrency,
50-
"nodes": node_dfs[0].values.tolist(),
51-
"relationships": relationship_dfs[0].values.tolist(),
53+
"nodes": nodes,
54+
"relationships": relationships,
5255
},
5356
)
5457

@@ -59,23 +62,32 @@ def _is_enterprise(self) -> bool:
5962

6063
return license == "Licensed"
6164

62-
def _node_query(self, node_df: DataFrame) -> str:
65+
def _node_query(self, node_df: DataFrame) -> Tuple[str, List[List[Any]]]:
66+
node_list = node_df.values.tolist()
6367
node_id_index = node_df.columns.get_loc("nodeId")
6468

6569
label_query = ""
6670
if "labels" in node_df.keys():
6771
label_index = node_df.columns.get_loc("labels")
6872
label_query = f", node[{label_index}] as labels"
6973

74+
# Make sure every node has a list of labels
75+
for node in node_list:
76+
labels = node[label_index]
77+
if isinstance(labels, List):
78+
continue
79+
node[label_index] = [labels]
80+
7081
property_query = ""
7182
property_columns: Set[str] = set(node_df.keys()) - {"nodeId", "labels"}
7283
if len(property_columns) > 0:
7384
property_queries = (f", node[{node_df.columns.get_loc(col)}] as {col}" for col in property_columns)
7485
property_query = "".join(property_queries)
7586

76-
return f"UNWIND $nodes as node RETURN node[{node_id_index}] as id{label_query}{property_query}"
87+
return f"UNWIND $nodes as node RETURN node[{node_id_index}] as id{label_query}{property_query}", node_list
7788

78-
def _relationship_query(self, rel_df: DataFrame) -> str:
89+
def _relationship_query(self, rel_df: DataFrame) -> Tuple[str, List[List[Any]]]:
90+
rel_list = rel_df.values.tolist()
7991
source_id_index = rel_df.columns.get_loc("sourceNodeId")
8092
target_id_index = rel_df.columns.get_loc("targetNodeId")
8193

@@ -93,5 +105,6 @@ def _relationship_query(self, rel_df: DataFrame) -> str:
93105
return (
94106
"UNWIND $relationships as relationship "
95107
f"RETURN relationship[{source_id_index}] as source, relationship[{target_id_index}] as target"
96-
f"{type_query}{property_query}"
108+
f"{type_query}{property_query}",
109+
rel_list,
97110
)

graphdatascience/tests/integration/test_graph_ops.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def test_graph_alpha_construct_without_arrow(gds_without_arrow: GraphDataScience
357357
nodes = pandas.DataFrame(
358358
{
359359
"nodeId": [0, 1, 2, 3],
360-
"labels": [["A"], ["B"], ["C"], ["D"]],
360+
"labels": [["A"], "B", ["C", "A"], ["D"]],
361361
"propA": [1337, 42, 8, 133742],
362362
"propB": [1338, 43, 9, 133743],
363363
}
@@ -377,6 +377,8 @@ def test_graph_alpha_construct_without_arrow(gds_without_arrow: GraphDataScience
377377
assert G.name() == "hello"
378378
assert G.node_count() == 4
379379
assert G.relationship_count() == 4
380+
assert set(G.node_labels()) == {"A", "B", "C", "D"}
381+
assert set(G.relationship_types()) == {"REL", "REL2"}
380382
assert set(G.node_properties("A")) == {"propA", "propB"}
381383
assert set(G.relationship_properties("REL")) == {"relPropA", "relPropB"}
382384

0 commit comments

Comments
 (0)