From ec0486bd1f639f9535ae25fe0ebd3fb1b2666790 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 23 Oct 2026 20:58:38 +0800 Subject: [PATCH 1/2] adding smart graph test --- .gitignore | 2 ++ tests/test_graph.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/.gitignore b/.gitignore index 3494dcdb..a9b63379 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,5 @@ node_modules/ # devcontainers .devcontainer + +test-results/ diff --git a/tests/test_graph.py b/tests/test_graph.py index fd3242fe..778ee843 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -2,6 +2,7 @@ from packaging import version from arango.collection import EdgeCollection +from arango.errno import INVALID_DISJOINT_SMART_EDGE from arango.exceptions import ( DocumentDeleteError, DocumentGetError, @@ -35,6 +36,59 @@ ) +@pytest.mark.parametrize( + "smart_field,disjoint", + [(None, False), ("region", False), ("region", True)], + ids=["enterprise", "smart", "disjoint-smart"], +) +def test_graph_create_smart_options(db, cluster, skip_tests, smart_field, disjoint): + if "enterprise" in skip_tests: + pytest.skip("Only for ArangoDB enterprise edition") + if not cluster: + pytest.skip("Only for ArangoDB clusters") + + graph_name = generate_graph_name() + vertices = generate_col_name() + edges = generate_col_name() + graph = db.create_graph( + graph_name, + edge_definitions=[ + { + "edge_collection": edges, + "from_vertex_collections": [vertices], + "to_vertex_collections": [vertices], + } + ], + smart=True, + smart_field=smart_field, + disjoint=disjoint, + shard_count=3, + ) + try: + properties = db.graph(graph_name).properties() + assert properties["smart"] is True + assert properties["disjoint"] is disjoint + assert properties.get("smart_field", "") == (smart_field or "") + assert properties["shard_count"] == 3 + + first = graph.insert_vertex(vertices, {"region": "eu"}) + second = graph.insert_vertex(vertices, {"region": "eu"}) + third = graph.insert_vertex(vertices, {"region": "us"}) + edge = graph.insert_edge(edges, {"_from": first["_id"], "_to": second["_id"]}) + assert graph.has_edge(edge["_id"]) + + cross_region_edge = {"_from": first["_id"], "_to": third["_id"]} + if disjoint: + with pytest.raises(DocumentInsertError) as err: + graph.insert_edge(edges, cross_region_edge) + assert err.value.error_code == INVALID_DISJOINT_SMART_EDGE + else: + edge = graph.insert_edge(edges, cross_region_edge) + assert graph.has_edge(edge["_id"]) + finally: + db.delete_graph(graph_name, drop_collections=True) + + def test_graph_properties(graph, bad_graph, db): assert repr(graph) == f"" From 809d6f2fa24a577bb9dd0332a9cd7a82c748f736 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 23 Oct 2026 21:14:40 +0800 Subject: [PATCH 2/2] Move smart and disjoint flags under options, add enterprise graph integration coverage, and clarify graph creation documentation. --- arango/database.py | 33 +++++++++++++++------------------ docs/graph.rst | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/arango/database.py b/arango/database.py index 627957f1..a0a51ff9 100644 --- a/arango/database.py +++ b/arango/database.py @@ -1898,25 +1898,22 @@ def create_graph( :param orphan_collections: Names of additional vertex collections that are not in edge definitions. :type orphan_collections: [str] | None - :param smart: If set to True, sharding is enabled (see parameter - **smart_field** below). Applies only to enterprise version of - ArangoDB. + :param smart: If set to True, create a SmartGraph when **smart_field** + is specified, or an EnterpriseGraph otherwise. Applies only to enterprise + version of ArangoDB. :type smart: bool | None :param disjoint: If set to True, create a disjoint SmartGraph instead - of a regular SmartGraph. Applies only to enterprise version of - ArangoDB. + of a regular SmartGraph. Only has an effect with **smart_field** + or **smart**. Applies only to enterprise version of ArangoDB. :type disjoint: bool | None :param smart_field: Document field used to shard the vertices of the - graph. To use this, parameter **smart** must be set to True and - every vertex in the graph must have the smart field. Applies only - to enterprise version of ArangoDB. NOTE: If this field is - None and **smart** is True, an Enterprise Graph will be created. + graph. Setting this creates a SmartGraph, even if **smart** is + omitted or False. Every vertex in the graph must have this field. + Applies only to enterprise version of ArangoDB. :type smart_field: str | None :param shard_count: Number of shards used for every collection in the - graph. To use this, parameter **smart** must be set to True and - every vertex in the graph must have the smart field. This number - cannot be modified later once set. Applies only to enterprise - version of ArangoDB. + graph. This number cannot be modified later once set. Used for + clusters only. :type shard_count: int | None :param replication_factor: Number of copies of each shard on different servers in a cluster. Allowed values are 1 (only one copy is kept @@ -1969,11 +1966,11 @@ def create_graph( ] if orphan_collections is not None: data["orphanCollections"] = orphan_collections - if smart is not None: # pragma: no cover - data["isSmart"] = smart - if disjoint is not None: # pragma: no cover - data["isDisjoint"] = disjoint - if smart_field is not None: # pragma: no cover + if smart is not None: + data["options"]["isSmart"] = smart + if disjoint is not None: + data["options"]["isDisjoint"] = disjoint + if smart_field is not None: data["options"]["smartGraphAttribute"] = smart_field if shard_count is not None: # pragma: no cover data["options"]["numberOfShards"] = shard_count diff --git a/docs/graph.rst b/docs/graph.rst index 88d0bcc0..bd482678 100644 --- a/docs/graph.rst +++ b/docs/graph.rst @@ -40,6 +40,37 @@ For more information, refer to `ArangoDB manual`_. # Delete the graph. db.delete_graph('school') +Graph creation options +====================== + +To create an EnterpriseGraph, pass ``smart=True`` and omit ``smart_field``. +EnterpriseGraphs use optimized graph sharding without a user-defined smart +field. + +To create a SmartGraph, set ``smart_field`` to the vertex attribute used for +sharding (``smart=True`` is then optional).Set ``disjoint=True`` alongside +``smart_field`` to create a Disjoint SmartGraph, which rejects edges between +vertices with different smart field values. + +For example, on an enterprise cluster: + +.. code-block:: python + + regional = db.create_graph( + 'regional', + edge_definitions=[{ + 'edge_collection': 'routes', + 'from_vertex_collections': ['places'], + 'to_vertex_collections': ['places'], + }], + smart_field='region', + disjoint=True, + shard_count=3, + ) + +See :meth:`arango.database.StandardDatabase.create_graph` for all creation +options. + .. _edge-definitions: Edge Definitions