Skip to content

Commit 575c6a9

Browse files
committed
Fix filters parameter
1 parent 1359a2d commit 575c6a9

File tree

3 files changed

+58
-25
lines changed

3 files changed

+58
-25
lines changed

infrahub_sdk/client.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,6 @@ async def _process_nodes_and_relationships(
539539
response: dict[str, Any],
540540
schema_kind: str,
541541
branch: str,
542-
prefetch_relationships: bool,
543542
timeout: int | None = None,
544543
) -> ProcessRelationsNode:
545544
"""Processes InfrahubNode and their Relationships from the GraphQL query response.
@@ -548,7 +547,6 @@ async def _process_nodes_and_relationships(
548547
response (dict[str, Any]): The response from the GraphQL query.
549548
schema_kind (str): The kind of schema being queried.
550549
branch (str): The branch name.
551-
prefetch_relationships (bool): Flag to indicate whether to prefetch relationship data.
552550
timeout (int, optional): Overrides default timeout used when querying the graphql API. Specified in seconds.
553551
554552
Returns:
@@ -564,10 +562,9 @@ async def _process_nodes_and_relationships(
564562
node = await InfrahubNode.from_graphql(client=self, branch=branch, data=item, timeout=timeout)
565563
nodes.append(node)
566564

567-
if prefetch_relationships:
568-
await node._process_relationships(
569-
node_data=item, branch=branch, related_nodes=related_nodes, timeout=timeout
570-
)
565+
await node._process_relationships(
566+
node_data=item, branch=branch, related_nodes=related_nodes, timeout=timeout
567+
)
571568

572569
return ProcessRelationsNode(nodes=nodes, related_nodes=related_nodes)
573570

@@ -814,7 +811,6 @@ async def process_page(page_offset: int, page_number: int) -> tuple[dict, Proces
814811
response=response,
815812
schema_kind=schema.kind,
816813
branch=branch,
817-
prefetch_relationships=prefetch_relationships,
818814
timeout=timeout,
819815
)
820816
return response, process_result

infrahub_sdk/node/node.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -730,19 +730,20 @@ async def generate_query_data_node(
730730
continue
731731

732732
rel_schema = self._schema.get_relationship(name=rel_name)
733-
734733
if not rel_schema or (not inherited and rel_schema.inherited):
735734
continue
736735

736+
# Don't fetch many attribute/parent relationships unless they are specified in `include`
737+
# TODO Why wouldn't we we fetch them if prefetch_relationships is True?
737738
if (
738739
rel_schema.cardinality == RelationshipCardinality.MANY # type: ignore[union-attr]
739740
and rel_schema.kind not in [RelationshipKind.ATTRIBUTE, RelationshipKind.PARENT] # type: ignore[union-attr]
740741
and not (include and rel_name in include)
741742
):
742743
continue
743744

744-
peer_data: dict[str, Any] = {}
745-
if rel_schema and prefetch_relationships:
745+
should_fetch_relationship = prefetch_relationships or (include is not None and rel_name in include)
746+
if rel_schema and should_fetch_relationship:
746747
peer_schema = await self._client.schema.get(kind=rel_schema.peer, branch=self._branch)
747748
peer_node = InfrahubNode(client=self._client, schema=peer_schema, branch=self._branch)
748749
peer_data = await peer_node.generate_query_data_node(
@@ -751,23 +752,26 @@ async def generate_query_data_node(
751752
property=property,
752753
)
753754

754-
if rel_schema and rel_schema.cardinality == "one":
755-
rel_data = RelatedNode._generate_query_data(peer_data=peer_data, property=property)
756-
# Nodes involved in a hierarchy are required to inherit from a common ancestor node, and graphql
757-
# tries to resolve attributes in this ancestor instead of actual node. To avoid
758-
# invalid queries issues when attribute is missing in the common ancestor, we use a fragment
759-
# to explicit actual node kind we are querying.
760-
if rel_schema.kind == RelationshipKind.HIERARCHY:
761-
data_node = rel_data["node"]
762-
rel_data["node"] = {}
763-
rel_data["node"][f"...on {rel_schema.peer}"] = data_node
764-
elif rel_schema and rel_schema.cardinality == "many":
765-
rel_data = RelationshipManager._generate_query_data(peer_data=peer_data, property=property)
755+
# TODO is there a reason why we fetch here even with prefetch_relationships == False?
756+
if rel_schema.cardinality == "one":
757+
rel_data = RelatedNode._generate_query_data(peer_data=peer_data, property=property)
758+
# Nodes involved in a hierarchy are required to inherit from a common ancestor node, and graphql
759+
# tries to resolve attributes in this ancestor instead of actual node. To avoid
760+
# invalid queries issues when attribute is missing in the common ancestor, we use a fragment
761+
# to explicit actual node kind we are querying.
762+
if rel_schema.kind == RelationshipKind.HIERARCHY:
763+
data_node = rel_data["node"]
764+
rel_data["node"] = {}
765+
rel_data["node"][f"...on {rel_schema.peer}"] = data_node
766+
elif rel_schema.cardinality == "many":
767+
rel_data = RelationshipManager._generate_query_data(peer_data=peer_data, property=property)
768+
else:
769+
raise ValueError(f"Unknown relationship cardinality {rel_schema.cardinality}")
766770

767-
data[rel_name] = rel_data
771+
data[rel_name] = rel_data
768772

769-
if insert_alias:
770-
data[rel_name]["@alias"] = f"__alias__{self._schema.kind}__{rel_name}"
773+
if insert_alias:
774+
data[rel_name]["@alias"] = f"__alias__{self._schema.kind}__{rel_name}"
771775

772776
return data
773777

tests/integration/test_node.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,39 @@ async def test_node_create_with_relationships_using_related_node(
8585
assert node_after.owner.peer.id == person_joe.id
8686
assert node_after.owner.peer.typename == "TestingPerson"
8787

88+
async def test_node_filters_include(
89+
self,
90+
default_branch: str,
91+
client: InfrahubClient,
92+
initial_schema: None,
93+
manufacturer_mercedes,
94+
person_joe,
95+
tag_red,
96+
) -> None:
97+
car = await client.create(
98+
kind=TESTING_CAR,
99+
name="Tiguan2",
100+
color="Black",
101+
manufacturer=manufacturer_mercedes,
102+
owner=person_joe,
103+
tags=[tag_red],
104+
)
105+
await car.save(allow_upsert=True)
106+
assert car.id is not None
107+
108+
node_after = await client.get(kind=TESTING_CAR, id=car.id)
109+
110+
with pytest.raises(ValueError):
111+
# match=r"Node must have at least one identifier (ID or HFID) to query it."
112+
_ = node_after.owner.peer
113+
114+
assert len(node_after.tags.peers) == 0
115+
116+
# Test both one and many relationships
117+
node_after = await client.get(kind=TESTING_CAR, id=car.id, include=["tags", "owner"])
118+
assert [tag.id for tag in node_after.tags.peers] == [tag_red.id]
119+
assert node_after.owner.peer.id == person_joe.id, f"{person_joe.id=}"
120+
88121
async def test_node_update_with_original_data(
89122
self,
90123
default_branch: str,

0 commit comments

Comments
 (0)