-
Notifications
You must be signed in to change notification settings - Fork 26
Add common_parent
relationship attribute
#6626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
async def _validate_peer_parents( | ||
info: GraphQLResolveInfo, data: RelationshipNodesInput, source_node: Node, peers: dict[str, Node] | ||
) -> None: | ||
relationship_name = str(data.name) | ||
rel_schema = source_node.get_schema().get_relationship(name=relationship_name) | ||
if not rel_schema.common_parent: | ||
return | ||
|
||
graphql_context: GraphqlContext = info.context | ||
|
||
source_node_parent = await source_node.get_parent_relationship_peer( | ||
db=graphql_context.db, name=rel_schema.common_parent | ||
) | ||
if not source_node_parent: | ||
raise ValidationError(f"Node {source_node.id} ({source_node.get_kind()!r}) does not have a parent peer") | ||
|
||
parents: set[str] = {source_node_parent.id} | ||
for peer in peers.values(): | ||
peer_parent = await peer.get_parent_relationship_peer(db=graphql_context.db, name=rel_schema.common_parent) | ||
if not peer_parent: | ||
raise ValidationError(f"Peer {peer.id} ({peer.get_kind()!r}) does not have a parent peer") | ||
parents.add(peer_parent.id) | ||
|
||
if len(parents) > 1: | ||
raise ValidationError( | ||
f"Cannot relate {source_node.id!r} to '{relationship_name}' peers that do not have the same parent" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like duplicating logic from another place, but the constraint checker cannot run here for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can't the RelationshipPeerParentConstraint
constraint run here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure yet, that the first thing I tried. I tried running it after during the transaction of the RelationshipAdd
mutation but it failed like neo4j.exceptions.ClientError: Explicit Transaction must be handled explicitly
. Running it before the transaction does not work because the checker isn't able to pick up the relationships are they are not set when it runs and therefore not picking up possible issues. Might need some more thoughts on this to figure it out.
75c1341
to
d07df47
Compare
CodSpeed Performance ReportMerging #6626 will not alter performanceComparing Summary
|
d07df47
to
d7e93ea
Compare
backend/infrahub/dependencies/builder/constraint/relationship_manager/peer_parent.py
Outdated
Show resolved
Hide resolved
async def _validate_peer_parents( | ||
info: GraphQLResolveInfo, data: RelationshipNodesInput, source_node: Node, peers: dict[str, Node] | ||
) -> None: | ||
relationship_name = str(data.name) | ||
rel_schema = source_node.get_schema().get_relationship(name=relationship_name) | ||
if not rel_schema.common_parent: | ||
return | ||
|
||
graphql_context: GraphqlContext = info.context | ||
|
||
source_node_parent = await source_node.get_parent_relationship_peer( | ||
db=graphql_context.db, name=rel_schema.common_parent | ||
) | ||
if not source_node_parent: | ||
raise ValidationError(f"Node {source_node.id} ({source_node.get_kind()!r}) does not have a parent peer") | ||
|
||
parents: set[str] = {source_node_parent.id} | ||
for peer in peers.values(): | ||
peer_parent = await peer.get_parent_relationship_peer(db=graphql_context.db, name=rel_schema.common_parent) | ||
if not peer_parent: | ||
raise ValidationError(f"Peer {peer.id} ({peer.get_kind()!r}) does not have a parent peer") | ||
parents.add(peer_parent.id) | ||
|
||
if len(parents) > 1: | ||
raise ValidationError( | ||
f"Cannot relate {source_node.id!r} to '{relationship_name}' peers that do not have the same parent" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can't the RelationshipPeerParentConstraint
constraint run here?
5c37d03
to
040873f
Compare
@@ -38,4 +38,6 @@ async def check( | |||
relationship_manager: RelationshipManager = getattr(node, relationship_name) | |||
await relationship_manager.fetch_relationship_ids(db=db, force_refresh=True) | |||
for relationship_constraint in self.relationship_manager_constraints: | |||
await relationship_constraint.check(relm=relationship_manager, node_schema=node.get_schema()) | |||
await relationship_constraint.check( | |||
relm=relationship_manager, node_schema=node.get_schema(), node=node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we're adding the node as an argument here and we can access the schema with node.get_schema() the node_schema parameter gets a bit redundant now. But we can perhaps consider removing that as a cleanup step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do that in a dedicated PR as it needs to change some code in other constraint checkers.
This relationship attribute is used to specify that peers of a given relationship must share a common parent with the source object. While the parent of the source object is infered automatically (as there is only one parent per object), the `common_parent` value must be set to the name of the parent relationship of the peer schema.
They will be left like that until we have proper constraint validators in place.
cdb48cb
to
f7d9fe7
Compare
This relationship attribute is used to specify that peers of a given
relationship must share a common parent with the source object. While
the parent of the source object is infered automatically (as there is
only one parent per object), the
common_parent
value must be set tothe name of the parent relationship of the peer schema.