diff --git a/graphdatascience/graph_data_science.py b/graphdatascience/graph_data_science.py index 01f353b19..5a36b1e64 100644 --- a/graphdatascience/graph_data_science.py +++ b/graphdatascience/graph_data_science.py @@ -83,8 +83,8 @@ def __init__( warnings.warn( DeprecationWarning( f"Client does not support the given server version `{self._server_version}`." - + "We recommend to either update the GDS server version or use a compatible version of the `graphdatascience` package." - + "Please refer to the compatibility matrix at https://neo4j.com/docs/graph-data-science-client/current/installation/#python-client-system-requirements." + + " We recommend to either update the GDS server version or use a compatible version of the `graphdatascience` package." + + " Please refer to the compatibility matrix at https://neo4j.com/docs/graph-data-science-client/current/installation/#python-client-system-requirements." ) ) diff --git a/graphdatascience/tests/unit/conftest.py b/graphdatascience/tests/unit/conftest.py index 6009f5206..abc9b1648 100644 --- a/graphdatascience/tests/unit/conftest.py +++ b/graphdatascience/tests/unit/conftest.py @@ -20,7 +20,7 @@ from graphdatascience.session.dbms_connection_info import DbmsConnectionInfo # Should mirror the latest GDS server version under development. -DEFAULT_SERVER_VERSION = ServerVersion(2, 6, 0) +DEFAULT_SERVER_VERSION = ServerVersion(2, 10, 0) QueryResult = Union[DataFrame, Exception] QueryResultMap = Dict[str, QueryResult] # Substring -> QueryResult diff --git a/graphdatascience/tests/unit/test_error_handling.py b/graphdatascience/tests/unit/test_error_handling.py index 091a59f88..0176a8893 100644 --- a/graphdatascience/tests/unit/test_error_handling.py +++ b/graphdatascience/tests/unit/test_error_handling.py @@ -15,7 +15,7 @@ ) -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) # Something later than 2.1.0 +@pytest.mark.parametrize("server_version", [ServerVersion(2, 10, 0)]) # Something later than 2.1.0 def test_incompatible_server_version(runner: QueryRunner, gds: GraphDataScience) -> None: G = Graph("dummy", runner) with pytest.raises( diff --git a/graphdatascience/tests/unit/test_graph_construct.py b/graphdatascience/tests/unit/test_graph_construct.py index fe4338ae2..65991f21f 100644 --- a/graphdatascience/tests/unit/test_graph_construct.py +++ b/graphdatascience/tests/unit/test_graph_construct.py @@ -2,12 +2,10 @@ from pandas import DataFrame from graphdatascience.graph_data_science import GraphDataScience -from graphdatascience.server_version.server_version import ServerVersion from .conftest import CollectingQueryRunner -@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)]) def test_graph_project_based_construct_without_arrow(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: nodes = DataFrame( { @@ -28,54 +26,22 @@ def test_graph_project_based_construct_without_arrow(runner: CollectingQueryRunn runner.add__mock_result("gds.debug.sysInfo", DataFrame([{"gdsEdition": "Unlicensed"}])) gds.graph.construct("hello", nodes, relationships, concurrency=2) - expected_node_query = "UNWIND $nodes as node RETURN node[0] as id, node[1] as labels, node[2] as propA" - expected_relationship_query = ( - "UNWIND $relationships as relationship RETURN " - "relationship[0] as source, relationship[1] as target, " - "relationship[2] as type, relationship[3] as relPropA" - ) - expected_proc_query = ( - "CALL gds.graph.project.cypher(" - "$graph_name, " - "$node_query, " - "$relationship_query, " - "{readConcurrency: $read_concurrency, parameters: { nodes: $nodes, relationships: $relationships }})" + expected_query = ( + "UNWIND $data AS data WITH data, " + "CASE WHEN data[6] THEN data[5] ELSE null END AS sourceNodeLabels, " + "CASE WHEN data[3] THEN data[2] ELSE null END AS relationshipType, " + "CASE WHEN data[10] THEN data[9] ELSE null END AS targetNodeId, " + "\nCASE WHEN data[8] THEN data[7] ELSE null END AS sourceNodeProperties, " + "\nCASE WHEN data[1] THEN data[0] ELSE null END AS relationshipProperties " + "RETURN gds.graph.project($graph_name, data[4], targetNodeId, {sourceNodeLabels: sourceNodeLabels, targetNodeLabels: NULL, sourceNodeProperties: sourceNodeProperties, targetNodeProperties: NULL, relationshipType: relationshipType, relationshipProperties: relationshipProperties}, $configuration)" ) - assert runner.last_query() == expected_proc_query - assert runner.last_params() == { - "nodes": nodes.values.tolist(), - "relationships": relationships.values.tolist(), - "read_concurrency": 2, - "graph_name": "hello", - "node_query": expected_node_query, - "relationship_query": expected_relationship_query, - } + assert runner.last_query() == expected_query -@pytest.mark.parametrize( - "server_version, tier, target_node_labels, target_node_properties, properties_key, in_between_configs", - [ - (ServerVersion(2, 3, 0), ".alpha", "", "", "properties", "}, {"), - ( - ServerVersion(2, 4, 0), - "", - ", targetNodeLabels: NULL", - ", targetNodeProperties: NULL", - "relationshipProperties", - ", ", - ), - ], - ids=["2.3.0 - Alpha Cypher Aggregation", "2.4.0 - New Cypher projection"], -) def test_multi_df( runner: CollectingQueryRunner, gds: GraphDataScience, - tier: str, - target_node_labels: str, - target_node_properties: str, - properties_key: str, - in_between_configs: str, ) -> None: nodes = [ DataFrame({"nodeId": [0, 1], "labels": ["a", "a"], "property": [6.0, 7.0]}), @@ -99,13 +65,12 @@ def test_multi_df( " CASE WHEN data[3] THEN data[2] ELSE null END AS relationshipType," " CASE WHEN data[10] THEN data[9] ELSE null END AS targetNodeId," " CASE WHEN data[8] THEN data[7] ELSE null END AS sourceNodeProperties," - f" CASE WHEN data[1] THEN data[0] ELSE null END AS {properties_key}" - f" RETURN gds{tier}.graph.project(" + " CASE WHEN data[1] THEN data[0] ELSE null END AS relationshipProperties" + " RETURN gds.graph.project(" "$graph_name, data[4], targetNodeId, {" - f"sourceNodeLabels: sourceNodeLabels{target_node_labels}, " - f"sourceNodeProperties: sourceNodeProperties{target_node_properties}" - f"{in_between_configs}" - f"relationshipType: relationshipType, {properties_key}: {properties_key}" + "sourceNodeLabels: sourceNodeLabels, targetNodeLabels: NULL, " + "sourceNodeProperties: sourceNodeProperties, targetNodeProperties: NULL, " + "relationshipType: relationshipType, relationshipProperties: relationshipProperties" "}, $configuration)" ) @@ -131,29 +96,9 @@ def test_multi_df( } -@pytest.mark.parametrize( - "server_version, tier, target_node_labels, target_node_properties, properties_key, in_between_configs", - [ - (ServerVersion(2, 3, 0), ".alpha", "", "", "properties", "}, {"), - ( - ServerVersion(2, 4, 0), - "", - ", targetNodeLabels: NULL", - ", targetNodeProperties: NULL", - "relationshipProperties", - ", ", - ), - ], - ids=["2.3.0 - Alpha Cypher Aggregation", "2.4.0 - New Cypher projection"], -) def test_graph_aggregation_based_construct_without_arrow( runner: CollectingQueryRunner, gds: GraphDataScience, - tier: str, - target_node_labels: str, - target_node_properties: str, - properties_key: str, - in_between_configs: str, ) -> None: nodes = DataFrame( { @@ -184,13 +129,12 @@ def test_graph_aggregation_based_construct_without_arrow( " CASE WHEN data[3] THEN data[2] ELSE null END AS relationshipType," " CASE WHEN data[10] THEN data[9] ELSE null END AS targetNodeId," " CASE WHEN data[8] THEN data[7] ELSE null END AS sourceNodeProperties," - f" CASE WHEN data[1] THEN data[0] ELSE null END AS {properties_key}" - f" RETURN gds{tier}.graph.project(" + " CASE WHEN data[1] THEN data[0] ELSE null END AS relationshipProperties" + " RETURN gds.graph.project(" "$graph_name, data[4], targetNodeId, {" - f"sourceNodeLabels: sourceNodeLabels{target_node_labels}, " - f"sourceNodeProperties: sourceNodeProperties{target_node_properties}" - f"{in_between_configs}" - f"relationshipType: relationshipType, {properties_key}: {properties_key}" + "sourceNodeLabels: sourceNodeLabels, targetNodeLabels: NULL, " + "sourceNodeProperties: sourceNodeProperties, targetNodeProperties: NULL, " + "relationshipType: relationshipType, relationshipProperties: relationshipProperties" "}, $configuration)" ) @@ -213,7 +157,6 @@ def test_graph_aggregation_based_construct_without_arrow( } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 3, 0)]) def test_graph_aggregation_based_construct_without_arrow_with_overlapping_property_columns( runner: CollectingQueryRunner, gds: GraphDataScience ) -> None: @@ -242,7 +185,6 @@ def test_graph_aggregation_based_construct_without_arrow_with_overlapping_proper gds.graph.construct("hello", nodes, relationships, concurrency=2) -@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)]) def test_graph_construct_validate_df_columns(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: nodes = DataFrame({"nodeIds": [0, 1]}) relationships = DataFrame({"sourceNodeId": [0, 1], "TargetNodeIds": [1, 0]}) @@ -254,7 +196,6 @@ def test_graph_construct_validate_df_columns(runner: CollectingQueryRunner, gds: gds.graph.construct("hello", nodes, relationships, concurrency=2) -@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)]) def test_graph_alpha_construct_backward_compat(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: nodes = DataFrame( { diff --git a/graphdatascience/tests/unit/test_graph_cypher.py b/graphdatascience/tests/unit/test_graph_cypher.py index b169e4a3c..ea4cd560b 100644 --- a/graphdatascience/tests/unit/test_graph_cypher.py +++ b/graphdatascience/tests/unit/test_graph_cypher.py @@ -3,12 +3,10 @@ from graphdatascience.graph.graph_cypher_runner import GraphCypherRunner from graphdatascience.graph_data_science import GraphDataScience -from graphdatascience.server_version.server_version import ServerVersion from .conftest import CollectingQueryRunner -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_simple(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "g", "don't squeeze": "me now"}]])) @@ -20,7 +18,6 @@ def test_simple(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: assert runner.last_query() == "MATCH (s)-->(t) RETURN gds.graph.project('g', s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_fstring(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "g", "don't squeeze": "me now"}]])) @@ -33,7 +30,6 @@ def test_fstring(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: assert runner.last_query() == "MATCH (s)-->(t) RETURN gds.graph.project('g', s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_expression(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "gg", "don't squeeze": "me now"}]])) @@ -45,7 +41,6 @@ def test_expression(runner: CollectingQueryRunner, gds: GraphDataScience) -> Non assert runner.last_query() == "WITH 'g' AS suffix MATCH (s)-->(t) RETURN gds.graph.project('g' + suffix, s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_with_parameter(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "g", "don't squeeze": "me now"}]])) @@ -57,7 +52,6 @@ def test_with_parameter(runner: CollectingQueryRunner, gds: GraphDataScience) -> assert runner.last_query() == "MATCH (s)-->(t) RETURN gds.graph.project($the_graph, s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_with_lots_of_whitespace(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "g", "don't squeeze": "me now"}]])) @@ -69,7 +63,6 @@ def test_with_lots_of_whitespace(runner: CollectingQueryRunner, gds: GraphDataSc assert runner.last_query() == "MATCH (s)-->(t) RETURN gds .graph. project\n(\t'g' ,s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_extracting_graph_name(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: runner.set__mock_result(DataFrame([[{"graphName": "the graph", "don't squeeze": "me now"}]])) @@ -81,7 +74,6 @@ def test_extracting_graph_name(runner: CollectingQueryRunner, gds: GraphDataScie assert runner.last_query() == "MATCH (s)-->(t) RETURN gds.graph.project('g', s, t)" -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_with_return_not_being_last(gds: GraphDataScience) -> None: with pytest.raises( ValueError, @@ -90,7 +82,6 @@ def test_with_return_not_being_last(gds: GraphDataScience) -> None: gds.graph.cypher.project("MATCH (s)-->(t) RETURN gds.graph.project($graph_name, s, t) AS graph") -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_with_no_return(gds: GraphDataScience) -> None: with pytest.raises( ValueError, @@ -99,7 +90,6 @@ def test_with_no_return(gds: GraphDataScience) -> None: gds.graph.cypher.project("MATCH (s)-->(t)") -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_with_multiple_returns(gds: GraphDataScience) -> None: with pytest.raises( ValueError, diff --git a/graphdatascience/tests/unit/test_graph_ops.py b/graphdatascience/tests/unit/test_graph_ops.py index a672bfee5..5c0806f9f 100644 --- a/graphdatascience/tests/unit/test_graph_ops.py +++ b/graphdatascience/tests/unit/test_graph_ops.py @@ -183,7 +183,6 @@ def test_graph_streamNodeProperty(runner: CollectingQueryRunner, gds: GraphDataS } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_nodeProperty_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -232,7 +231,6 @@ def test_graph_streamNodeProperties(runner: CollectingQueryRunner, gds: GraphDat } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_nodeProperties_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -283,7 +281,6 @@ def test_graph_streamRelationshipProperty(runner: CollectingQueryRunner, gds: Gr } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_relationshipProperty_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -354,7 +351,6 @@ def test_graph_streamRelationshipProperties(runner: CollectingQueryRunner, gds: } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_relationshipProperties_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -397,7 +393,6 @@ def test_graph_relationshipProperties_stream(runner: CollectingQueryRunner, gds: } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 4, 0)]) def test_graph_relationshipProperties_write(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -441,7 +436,6 @@ def test_graph_writeNodeProperties(runner: CollectingQueryRunner, gds: GraphData } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_nodeProperties_write(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -492,7 +486,6 @@ def test_graph_writeRelationship(runner: CollectingQueryRunner, gds: GraphDataSc } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_relationship_write(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -521,7 +514,6 @@ def test_graph_relationship_write(runner: CollectingQueryRunner, gds: GraphDataS } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 5, 0)]) def test_graph_nodeLabel_write(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -534,7 +526,6 @@ def test_graph_nodeLabel_write(runner: CollectingQueryRunner, gds: GraphDataScie } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 5, 0)]) def test_graph_nodeLabel_mutate(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -547,34 +538,6 @@ def test_graph_nodeLabel_mutate(runner: CollectingQueryRunner, gds: GraphDataSci } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 0, 0)]) -def test_graph_removeNodeProperties_20(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: - G, _ = gds.graph.project("g", "*", "*") - - gds.graph.removeNodeProperties(G, ["dummyProp"], "dummyLabel", concurrency=2) - assert runner.last_query() == "CALL gds.graph.removeNodeProperties($graph_name, $properties, $entities, $config)" - assert runner.last_params() == { - "graph_name": "g", - "properties": ["dummyProp"], - "entities": "dummyLabel", - "config": {"concurrency": 2}, - } - - -@pytest.mark.parametrize("server_version", [ServerVersion(2, 1, 0)]) -def test_graph_removeNodeProperties_21(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: - G, _ = gds.graph.project("g", "*", "*") - - gds.graph.removeNodeProperties(G, ["dummyProp"], concurrency=2) - assert runner.last_query() == "CALL gds.graph.removeNodeProperties($graph_name, $properties, $config)" - assert runner.last_params() == { - "graph_name": "g", - "properties": ["dummyProp"], - "config": {"concurrency": 2}, - } - - -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_nodeProperties_remove_drop(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -595,7 +558,6 @@ def test_graph_deleteRelationships(runner: CollectingQueryRunner, gds: GraphData assert runner.last_params() == {"graph_name": "g", "relationship_type": "REL_A"} -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_relationships_drop(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -604,7 +566,6 @@ def test_graph_relationships_drop(runner: CollectingQueryRunner, gds: GraphDataS assert runner.last_params() == {"graph_name": "g", "relationship_type": "REL_A"} -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_property_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -613,7 +574,6 @@ def test_graph_property_stream(runner: CollectingQueryRunner, gds: GraphDataScie assert runner.last_params() == {"graph_name": "g", "graph_property": "prop", "config": {}} -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_property_drop(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -622,7 +582,6 @@ def test_graph_property_drop(runner: CollectingQueryRunner, gds: GraphDataScienc assert runner.last_params() == {"graph_name": "g", "graph_property": "prop", "config": {}} -@pytest.mark.parametrize("server_version", [ServerVersion(2, 2, 0)]) def test_graph_relationships_stream(runner: CollectingQueryRunner, gds: GraphDataScience) -> None: G, _ = gds.graph.project("g", "*", "*") @@ -704,7 +663,6 @@ def test_graph_relationships_to_undirected(runner: CollectingQueryRunner, gds: G } -@pytest.mark.parametrize("server_version", [ServerVersion(2, 7, 0)]) def test_remote_projection_all_configuration(runner: CollectingQueryRunner, aura_gds: AuraGraphDataScience) -> None: G, _ = aura_gds.graph.project( graph_name="g",