Skip to content

Commit 49c503b

Browse files
brs96orazve
andcommitted
Add tests for deprecation warnings
Co-authored-by: Olga Razvenskaia <olga.razvenskaia@neo4j.com>
1 parent 0a46ae4 commit 49c503b

File tree

3 files changed

+95
-20
lines changed

3 files changed

+95
-20
lines changed

graphdatascience/graph/graph_alpha_proc_runner.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from typing import List, Optional, Union
23

34
from pandas import DataFrame
@@ -11,7 +12,6 @@
1112
from .graph_alpha_project_runner import GraphAlphaProjectRunner
1213
from .graph_entity_ops_runner import GraphLabelRunner, GraphPropertyRunner
1314
from .graph_object import Graph
14-
from .graph_proc_runner import GraphProcRunner
1515
from .graph_sample_runner import GraphAlphaSampleRunner
1616

1717

@@ -37,7 +37,7 @@ def project(self) -> GraphAlphaProjectRunner:
3737
return GraphAlphaProjectRunner(self._query_runner, self._namespace, self._server_version)
3838

3939
@client_only_endpoint("gds.alpha.graph")
40-
@deprecation_warning("gds.graph", ServerVersion(2, 1, 0))
40+
@deprecation_warning("gds.graph.construct", ServerVersion(2, 1, 0))
4141
@compatible_with("construct", min_inclusive=ServerVersion(2, 1, 0))
4242
def construct(
4343
self,
@@ -47,5 +47,39 @@ def construct(
4747
concurrency: int = 4,
4848
undirected_relationship_types: Optional[List[str]] = None,
4949
) -> Graph:
50-
graph_proc_runner = GraphProcRunner(self._query_runner, f"{self._namespace}.graph", self._server_version)
51-
return graph_proc_runner.construct(graph_name, nodes, relationships, concurrency, undirected_relationship_types)
50+
nodes = nodes if isinstance(nodes, List) else [nodes]
51+
relationships = relationships if isinstance(relationships, List) else [relationships]
52+
53+
errors = []
54+
55+
exists = self._query_runner.run_query(
56+
f"CALL gds.graph.exists('{graph_name}') YIELD exists", custom_error=False
57+
).squeeze()
58+
59+
# compare against True as (1) unit tests return None here and (2) numpys True does not work with `is True`.
60+
if exists == True: # noqa: E712
61+
errors.append(
62+
f"Graph '{graph_name}' already exists. Please drop the existing graph or use a different name."
63+
)
64+
65+
for idx, node_df in enumerate(nodes):
66+
if "nodeId" not in node_df.columns.values:
67+
errors.append(f"Node dataframe at index {idx} needs to contain a 'nodeId' column.")
68+
69+
for idx, rel_df in enumerate(relationships):
70+
for expected_col in ["sourceNodeId", "targetNodeId"]:
71+
if expected_col not in rel_df.columns.values:
72+
errors.append(f"Relationship dataframe at index {idx} needs to contain a '{expected_col}' column.")
73+
74+
if self._server_version < ServerVersion(2, 3, 0) and undirected_relationship_types:
75+
errors.append("The parameter 'undirected_relationship_types' is only supported since GDS 2.3.0.")
76+
77+
if len(errors) > 0:
78+
raise ValueError(os.linesep.join(errors))
79+
80+
constructor = self._query_runner.create_graph_constructor(
81+
graph_name, concurrency, undirected_relationship_types
82+
)
83+
constructor.run(nodes, relationships)
84+
85+
return Graph(graph_name, self._query_runner, self._server_version)

graphdatascience/tests/integration/test_graph_construct.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def test_roundtrip_with_arrow_encrypted(gds_with_tls: GraphDataScience) -> None:
188188
rel_df = gds_with_tls.graph.streamRelationshipProperty(G, "relX")
189189
node_df = gds_with_tls.graph.streamNodeProperty(G, "x")
190190

191-
G_2 = gds_with_tls.alpha.graph.construct("arrowGraph", node_df, rel_df)
191+
G_2 = gds_with_tls.graph.construct("arrowGraph", node_df, rel_df)
192192

193193
try:
194194
assert G.node_count() == G_2.node_count()
@@ -198,7 +198,7 @@ def test_roundtrip_with_arrow_encrypted(gds_with_tls: GraphDataScience) -> None:
198198

199199

200200
@pytest.mark.filterwarnings("ignore: GDS Enterprise users can use Apache Arrow")
201-
def test_graph_alpha_construct_without_arrow(gds_without_arrow: GraphDataScience) -> None:
201+
def test_graph_construct_without_arrow(gds_without_arrow: GraphDataScience) -> None:
202202
nodes = DataFrame(
203203
{
204204
"nodeId": [0, 1, 2, 3],
@@ -218,7 +218,7 @@ def test_graph_alpha_construct_without_arrow(gds_without_arrow: GraphDataScience
218218
}
219219
)
220220

221-
G = gds_without_arrow.alpha.graph.construct("hello", nodes, relationships)
221+
G = gds_without_arrow.graph.construct("hello", nodes, relationships)
222222

223223
try:
224224
assert G.name() == "hello"
@@ -234,7 +234,7 @@ def test_graph_alpha_construct_without_arrow(gds_without_arrow: GraphDataScience
234234

235235
@pytest.mark.filterwarnings("ignore: GDS Enterprise users can use Apache Arrow")
236236
@pytest.mark.compatible_with(min_inclusive=ServerVersion(2, 3, 0))
237-
def test_graph_alpha_construct_undirected_without_arrow(gds_without_arrow: GraphDataScience) -> None:
237+
def test_graph_construct_undirected_without_arrow(gds_without_arrow: GraphDataScience) -> None:
238238
nodes = DataFrame(
239239
{
240240
"nodeId": [0, 1, 2, 3],
@@ -249,7 +249,7 @@ def test_graph_alpha_construct_undirected_without_arrow(gds_without_arrow: Graph
249249
}
250250
)
251251

252-
G = gds_without_arrow.alpha.graph.construct("hello", nodes, relationships, undirected_relationship_types=["REL2"])
252+
G = gds_without_arrow.graph.construct("hello", nodes, relationships, undirected_relationship_types=["REL2"])
253253

254254
try:
255255
assert G.name() == "hello"
@@ -262,7 +262,7 @@ def test_graph_alpha_construct_undirected_without_arrow(gds_without_arrow: Graph
262262

263263
@pytest.mark.filterwarnings("ignore: GDS Enterprise users can use Apache Arrow")
264264
@pytest.mark.compatible_with(max_exclusive=ServerVersion(2, 3, 0))
265-
def warn_for_graph_alpha_construct_undirected_without_arrow(gds_without_arrow: GraphDataScience) -> None:
265+
def warn_for_graph_construct_undirected_without_arrow(gds_without_arrow: GraphDataScience) -> None:
266266
nodes = DataFrame(
267267
{
268268
"nodeId": [0, 1, 2, 3],
@@ -277,7 +277,7 @@ def warn_for_graph_alpha_construct_undirected_without_arrow(gds_without_arrow: G
277277
)
278278

279279
with pytest.raises(ValueError):
280-
gds_without_arrow.alpha.graph.construct("hello", nodes, relationships, undirected_relationship_types=["REL2"])
280+
gds_without_arrow.graph.construct("hello", nodes, relationships, undirected_relationship_types=["REL2"])
281281

282282

283283
@pytest.mark.enterprise
@@ -297,7 +297,7 @@ def test_graph_construct_with_arrow(gds: GraphDataScience) -> None:
297297

298298
@pytest.mark.filterwarnings("ignore: GDS Enterprise users can use Apache Arrow")
299299
@pytest.mark.compatible_with(max_exlusive=ServerVersion(2, 3, 0))
300-
def warn_for_graph_alpha_construct_undirected_with_arrow(gds: GraphDataScience) -> None:
300+
def warn_for_graph_construct_undirected_with_arrow(gds: GraphDataScience) -> None:
301301
nodes = DataFrame(
302302
{
303303
"nodeId": [0, 1, 2, 3],
@@ -400,7 +400,7 @@ def test_graph_construct_without_arrow_enterprise_warning(gds_without_arrow: Gra
400400
relationships = DataFrame({"sourceNodeId": [0, 1, 2, 3], "targetNodeId": [1, 2, 3, 0]})
401401

402402
with pytest.warns(UserWarning):
403-
G = gds_without_arrow.alpha.graph.construct("hello", nodes, relationships)
403+
G = gds_without_arrow.graph.construct("hello", nodes, relationships)
404404
G.drop()
405405

406406

@@ -416,7 +416,7 @@ def test_graph_construct_without_arrow_multi_dfs(gds_without_arrow: GraphDataSci
416416
DataFrame({"sourceNodeId": [2, 3], "targetNodeId": [3, 0], "relationshipType": ["B", "B"]}),
417417
]
418418

419-
G = gds_without_arrow.alpha.graph.construct("hello", nodes, relationships)
419+
G = gds_without_arrow.graph.construct("hello", nodes, relationships)
420420

421421
assert G.name() == "hello"
422422
assert G.node_count() == 4
@@ -462,3 +462,24 @@ def test_graph_construct_with_arrow_no_db() -> None:
462462

463463
with pytest.raises(ValueError):
464464
gds.graph.construct("hello", nodes, relationships)
465+
466+
467+
@pytest.mark.filterwarnings("ignore: GDS Enterprise users can use Apache Arrow")
468+
def test_graph_alpha_construct_backward_compat_without_arrow(gds_without_arrow: GraphDataScience) -> None:
469+
nodes = DataFrame({"nodeId": [0, 1, 2, 3], "labels": [["A"], "B", ["C", "A"], ["D"]]})
470+
relationships = DataFrame(
471+
{"sourceNodeId": [0, 1, 2, 3], "targetNodeId": [1, 2, 3, 0], "relationshipType": ["REL", "REL", "REL", "REL2"]}
472+
)
473+
474+
with pytest.warns(DeprecationWarning):
475+
gds_without_arrow.alpha.graph.construct("hello", nodes, relationships)
476+
477+
478+
@pytest.mark.enterprise
479+
@pytest.mark.compatible_with(min_inclusive=ServerVersion(2, 1, 0))
480+
def test_graph_alpha_construct_backward_compat_with_arrow(gds: GraphDataScience) -> None:
481+
nodes = DataFrame({"nodeId": [0, 1, 2, 3]})
482+
relationships = DataFrame({"sourceNodeId": [0, 1, 2, 3], "targetNodeId": [1, 2, 3, 0]})
483+
484+
with pytest.warns(DeprecationWarning):
485+
gds.alpha.graph.construct("hello", nodes, relationships)

graphdatascience/tests/unit/test_graph_construct.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77

88

99
@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)])
10-
def test_graph_project_based_alpha_construct_without_arrow(
11-
runner: CollectingQueryRunner, gds: GraphDataScience
12-
) -> None:
10+
def test_graph_project_based_construct_without_arrow(runner: CollectingQueryRunner, gds: GraphDataScience) -> None:
1311
nodes = DataFrame(
1412
{
1513
"nodeId": [0, 1],
@@ -144,7 +142,7 @@ def test_multi_df(
144142
],
145143
ids=["2.3.0 - Alpha Cypher Aggregation", "2.4.0 - New Cypher projection"],
146144
)
147-
def test_graph_aggregation_based_alpha_construct_without_arrow(
145+
def test_graph_aggregation_based_construct_without_arrow(
148146
runner: CollectingQueryRunner,
149147
gds: GraphDataScience,
150148
tier: str,
@@ -210,7 +208,7 @@ def test_graph_aggregation_based_alpha_construct_without_arrow(
210208

211209

212210
@pytest.mark.parametrize("server_version", [ServerVersion(2, 3, 0)])
213-
def test_graph_aggregation_based_alpha_construct_without_arrow_with_overlapping_property_columns(
211+
def test_graph_aggregation_based_construct_without_arrow_with_overlapping_property_columns(
214212
runner: CollectingQueryRunner, gds: GraphDataScience
215213
) -> None:
216214
nodes = DataFrame(
@@ -236,9 +234,31 @@ def test_graph_aggregation_based_alpha_construct_without_arrow_with_overlapping_
236234

237235

238236
@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)])
239-
def test_graph_alpha_construct_validate_df_columns(runner: CollectingQueryRunner, gds: GraphDataScience) -> None:
237+
def test_graph_construct_validate_df_columns(runner: CollectingQueryRunner, gds: GraphDataScience) -> None:
240238
nodes = DataFrame({"nodeIds": [0, 1]})
241239
relationships = DataFrame({"sourceNodeId": [0, 1], "TargetNodeIds": [1, 0]})
242240

243241
with pytest.raises(ValueError, match=r"(.*'nodeId'.*\s.*'targetNodeId'.*)|(.*'targetNodeId'.*\s.*'nodeId'.*)"):
244242
gds.graph.construct("hello", nodes, relationships, concurrency=2)
243+
244+
245+
@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)])
246+
def test_graph_alpha_construct_backward_compat(runner: CollectingQueryRunner, gds: GraphDataScience) -> None:
247+
nodes = DataFrame(
248+
{
249+
"nodeId": [0, 1],
250+
"labels": [["A"], ["B"]],
251+
"propA": [1337, 42.1],
252+
}
253+
)
254+
relationships = DataFrame(
255+
{
256+
"sourceNodeId": [0, 1],
257+
"targetNodeId": [1, 0],
258+
"relationshipType": ["REL", "REL2"],
259+
"relPropA": [1337.2, 42],
260+
}
261+
)
262+
263+
with pytest.warns(DeprecationWarning):
264+
gds.alpha.graph.construct("hello", nodes, relationships, concurrency=2)

0 commit comments

Comments
 (0)