Skip to content

Commit

Permalink
Feature/import as (#1859)
Browse files Browse the repository at this point in the history
* impl import node as

* impl import nodes as

* impl import node/nodes as tests

* add import edge/edges as tests

* fix error msgs

* impl import as for py

* fix doc comments

* add review changes and fix tests

* ref

* ref, add tests

* fix storage

* fix test from #1857

* ren force to merge

* fix docs

---------

Co-authored-by: Shivam Kapoor <[email protected]>
Co-authored-by: Ben Steer <[email protected]>
  • Loading branch information
3 people authored Nov 22, 2024
1 parent e162209 commit e289e5a
Show file tree
Hide file tree
Showing 7 changed files with 1,394 additions and 199 deletions.
2 changes: 1 addition & 1 deletion python/tests/graphql/test_nodes_property_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def test_node_property_filter_equal_no_value_error(graph):
run_graphql_error_test(query, expected_error_message, graph())


@pytest.mark.parametrize("graph", [Graph])
@pytest.mark.parametrize("graph", [Graph, PersistentGraph])
def test_node_property_filter_equal_type_error(graph):
query = """
query {
Expand Down
231 changes: 231 additions & 0 deletions python/tests/test_graphdb/test_graphdb_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def test_import_into_graph():
assert res.properties.get("temp") == True
assert res.properties.constant.get("con") == 11

gg = Graph()
gg.add_node(1, "B")
with pytest.raises(Exception) as excinfo:
gg.import_nodes([g_a, g_b])
assert "Nodes already exist" in str(excinfo.value)
assert gg.node("A") is None

gg = Graph()
gg.import_nodes([g_a, g_b])
assert len(gg.nodes) == 2
Expand All @@ -35,11 +42,19 @@ def test_import_into_graph():
assert res.properties.as_dict() == props

e_c_d = g.add_edge(4, "C", "D")

gg = Graph()
gg.import_edges([e_a_b, e_c_d])
assert len(gg.nodes) == 4
assert len(gg.edges) == 2

gg = Graph()
gg.add_edge(1, "C", "D")
with pytest.raises(Exception) as excinfo:
gg.import_edges([e_a_b, e_c_d])
assert "Edges already exist" in str(excinfo.value)
assert gg.edge("A", "B") is None


def test_import_with_int():
g = Graph()
Expand All @@ -58,6 +73,222 @@ def test_import_with_int():
assert g2.count_nodes() == g.count_nodes()


def test_import_node_as():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

gg = Graph()
res = gg.import_node_as(a, "X")
assert res.name == "X"
assert res.history().tolist() == [1]

gg.add_node(1, "Y")

with pytest.raises(Exception) as excinfo:
gg.import_node_as(b, "Y")

assert "Node already exists" in str(excinfo.value)

assert gg.nodes.name == ["X", "Y"]
y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None


def test_import_node_as_merge():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

gg = Graph()
res = gg.import_node_as(a, "X")
assert res.name == "X"
assert res.history().tolist() == [1]

gg.add_node(1, "Y")
gg.import_node_as(b, "Y", True)

assert gg.nodes.name == ["X", "Y"]
y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1]
assert y.properties.get("temp") == True
assert y.properties.constant.get("con") == 11


def test_import_nodes_as():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

gg = Graph()
gg.add_node(1, "Y")

with pytest.raises(Exception) as excinfo:
gg.import_nodes_as([a, b], ["X", "Y"])

assert "Nodes already exist" in str(excinfo.value)

assert gg.node("X") == None

assert sorted(gg.nodes.name) == ["Y"]
y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None


def test_import_nodes_as_merge():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

gg = Graph()
gg.add_node(1, "Y")
gg.import_nodes_as([a, b], ["X", "Y"], True)

assert sorted(gg.nodes.name) == ["X", "Y"]
x = gg.node("X")
assert x.name == "X"
assert x.history().tolist() == [1]

y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1]
assert y.properties.get("temp") == True
assert y.properties.constant.get("con") == 11


def test_import_edge_as():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

e_a_b = g.add_edge(2, "A", "B", {"e_temp": True})
e_b_c = g.add_edge(2, "B", "C", {"e_temp": True})

gg = Graph()
gg.add_edge(1, "X", "Y")

gg.import_edge_as(e_b_c, ("Y", "Z"))

with pytest.raises(Exception) as excinfo:
gg.import_edge_as(e_a_b, ("X", "Y"))
assert "Edge already exists" in str(excinfo.value)

assert sorted(gg.nodes.name) == ["X", "Y", "Z"]
x = gg.node("X")
assert x.name == "X"
assert x.history().tolist() == [1]

y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1, 2]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None

e = gg.edge("X", "Y")
assert e.properties.get("e_temp") is None


def test_import_edge_as_merge():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})

e_a_b = g.add_edge(2, "A", "B", {"e_temp": True})

gg = Graph()
gg.add_edge(3, "X", "Y")
gg.import_edge_as(e_a_b, ("X", "Y"), True)

assert sorted(gg.nodes.name) == ["X", "Y"]
x = gg.node("X")
assert x.name == "X"
print(x.history())
assert x.history().tolist() == [2, 3]

y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [2, 3]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None

e = gg.edge("X", "Y")
assert e.properties.get("e_temp") == True


def test_import_edges_as():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})
c = g.add_node(1, "C")

e_a_b = g.add_edge(2, "A", "B", {"e_temp": True})
e_b_c = g.add_edge(2, "B", "C")

gg = Graph()
gg.add_edge(1, "Y", "Z")

with pytest.raises(Exception) as excinfo:
gg.import_edges_as([e_a_b, e_b_c], [("X", "Y"), ("Y", "Z")])
assert "Edges already exist" in str(excinfo.value)

assert sorted(gg.nodes.name) == ["Y", "Z"]

y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [1]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None

z = gg.node("Z")
assert z.name == "Z"
assert z.history().tolist() == [1]


def test_import_edges_as_merge():
g = Graph()
a = g.add_node(1, "A")
b = g.add_node(1, "B", {"temp": True})
b.add_constant_properties({"con": 11})
c = g.add_node(1, "C")

e_a_b = g.add_edge(2, "A", "B", {"e_temp": True})
e_b_c = g.add_edge(2, "B", "C")

gg = Graph()
gg.add_edge(3, "Y", "Z")
gg.import_edges_as([e_a_b, e_b_c], [("X", "Y"), ("Y", "Z")], True)

assert sorted(gg.nodes.name) == ["X", "Y", "Z"]

x = gg.node("X")
assert x.name == "X"
assert x.history().tolist() == [2]

y = gg.node("Y")
assert y.name == "Y"
assert y.history().tolist() == [2, 3]
assert y.properties.get("temp") is None
assert y.properties.constant.get("con") is None

z = gg.node("Z")
assert z.name == "Z"
assert z.history().tolist() == [2, 3]


def test_import_edges():
g = Graph()
g.add_node(1, 1)
Expand Down
6 changes: 6 additions & 0 deletions raphtory/src/core/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,15 @@ pub enum GraphError {
#[error("Node already exists with ID {0:?}")]
NodeExistsError(GID),

#[error("Nodes already exist with IDs: {0:?}")]
NodesExistError(Vec<GID>),

#[error("Edge already exists for nodes {0:?} {1:?}")]
EdgeExistsError(GID, GID),

#[error("Edges already exist with IDs: {0:?}")]
EdgesExistError(Vec<(GID, GID)>),

#[error("Node {0} does not exist")]
NodeMissingError(GID),

Expand Down
Loading

0 comments on commit e289e5a

Please sign in to comment.