@@ -595,31 +595,55 @@ def validate_schema_path(
595595 if not (SchemaElementPathType .ATTR & allowed_path_types ) and schema_attribute_path .is_type_attribute :
596596 raise ValueError (f"{ error_header } : this property only supports relationships not attributes" )
597597
598- if not (SchemaElementPathType .ALL_RELS & allowed_path_types ) and schema_attribute_path .is_type_relationship :
598+ if not (SchemaElementPathType .REL & allowed_path_types ) and schema_attribute_path .is_type_relationship :
599599 raise ValueError (f"{ error_header } : this property only supports attributes, not relationships" )
600600
601- if schema_attribute_path . is_type_relationship and schema_attribute_path .relationship_schema :
602- if (
603- schema_attribute_path .relationship_schema . cardinality == RelationshipCardinality . ONE
604- and not SchemaElementPathType . REL_ONE & allowed_path_types
605- ) :
601+ if not ( SchemaElementPathType . ATTR_NO_PROP & allowed_path_types ) and schema_attribute_path .is_type_attribute :
602+ required_properties = tuple (
603+ schema_attribute_path .attribute_schema . get_class (). get_allowed_property_in_path ()
604+ )
605+ if schema_attribute_path . attribute_property_name not in required_properties :
606606 raise ValueError (
607- f"{ error_header } : cannot use { schema_attribute_path . relationship_schema . name } relationship, "
608- " relationship must be of cardinality many "
607+ f"{ error_header } : invalid attribute, it must end with one of the following properties: "
608+ f" { ', ' . join ( required_properties ) } . (` { path } `) "
609609 )
610+
611+ if schema_attribute_path .is_type_relationship :
612+ if schema_attribute_path .relationship_schema .cardinality == RelationshipCardinality .ONE :
613+ if not SchemaElementPathType .REL_ONE & allowed_path_types :
614+ raise ValueError (
615+ f"{ error_header } : cannot use { schema_attribute_path .relationship_schema .name } relationship,"
616+ f" relationship must be of cardinality many. (`{ path } `)"
617+ )
618+ if (
619+ not SchemaElementPathType .REL_ONE_OPTIONAL & allowed_path_types
620+ and schema_attribute_path .relationship_schema .optional
621+ and not (
622+ schema_attribute_path .relationship_schema .name == "ip_namespace"
623+ and isinstance (node_schema , NodeSchema )
624+ and (node_schema .is_ip_address () or node_schema .is_ip_prefix )
625+ )
626+ ):
627+ raise ValueError (
628+ f"{ error_header } : cannot use { schema_attribute_path .relationship_schema .name } relationship,"
629+ f" relationship must be mandatory. (`{ path } `)"
630+ )
631+
610632 if (
611633 schema_attribute_path .relationship_schema .cardinality == RelationshipCardinality .MANY
612634 and not SchemaElementPathType .REL_MANY & allowed_path_types
613635 ):
614636 raise ValueError (
615637 f"{ error_header } : cannot use { schema_attribute_path .relationship_schema .name } relationship,"
616- " relationship must be of cardinality one"
638+ f " relationship must be of cardinality one (` { path } `) "
617639 )
618640
619- if schema_attribute_path .has_property and not SchemaElementPathType .RELS_ATTR & allowed_path_types :
620- raise ValueError (f"{ error_header } : cannot use attributes of related node, only the relationship" )
641+ if schema_attribute_path .has_property and not SchemaElementPathType .REL_ATTR & allowed_path_types :
642+ raise ValueError (
643+ f"{ error_header } : cannot use attributes of related node, only the relationship. (`{ path } `)"
644+ )
621645 if not schema_attribute_path .has_property and not SchemaElementPathType .RELS_NO_ATTR & allowed_path_types :
622- raise ValueError (f"{ error_header } : Must use attributes of related node" )
646+ raise ValueError (f"{ error_header } : Must use attributes of related node. (` { path } `) " )
623647
624648 return schema_attribute_path
625649
@@ -669,34 +693,15 @@ def validate_uniqueness_constraints(self) -> None:
669693
670694 for constraint_paths in node_schema .uniqueness_constraints :
671695 for constraint_path in constraint_paths :
672- schema_path = self .validate_schema_path (
696+ element_name = "uniqueness_constraints"
697+ self .validate_schema_path (
673698 node_schema = node_schema ,
674699 path = constraint_path ,
675- allowed_path_types = SchemaElementPathType .ATTR | SchemaElementPathType .REL_ONE_NO_ATTR ,
676- element_name = "uniqueness_constraints" ,
700+ allowed_path_types = SchemaElementPathType .ATTR_WITH_PROP
701+ | SchemaElementPathType .REL_ONE_MANDATORY_NO_ATTR ,
702+ element_name = element_name ,
677703 )
678704
679- if schema_path .is_type_attribute :
680- required_properties = tuple (
681- schema_path .attribute_schema .get_class ().get_allowed_property_in_path ()
682- )
683- if schema_path .attribute_property_name not in required_properties :
684- raise ValueError (
685- f"{ node_schema .kind } uniqueness contraint is invalid at attribute '{ schema_path .attribute_schema .name } ', it must "
686- f"end with one of the following properties: { ', ' .join (required_properties )} "
687- )
688-
689- if schema_path .is_type_relationship and schema_path .relationship_schema :
690- if schema_path .relationship_schema .optional and not (
691- schema_path .relationship_schema .name == "ip_namespace"
692- and isinstance (node_schema , NodeSchema )
693- and (node_schema .is_ip_address () or node_schema .is_ip_prefix )
694- ):
695- raise ValueError (
696- f"Only mandatory relation of cardinality one can be used in uniqueness_constraints,"
697- f" { schema_path .relationship_schema .name } is not mandatory. ({ constraint_path } )"
698- )
699-
700705 def validate_display_labels (self ) -> None :
701706 for name in self .all_names :
702707 node_schema = self .get (name = name , duplicate = False )
@@ -727,13 +732,14 @@ def validate_order_by(self) -> None:
727732 if not node_schema .order_by :
728733 continue
729734
730- allowed_types = SchemaElementPathType .ATTR | SchemaElementPathType .REL_ONE
735+ allowed_types = SchemaElementPathType .ATTR_WITH_PROP | SchemaElementPathType .REL_ONE_ATTR_WITH_PROP
731736 for order_by_path in node_schema .order_by :
737+ element_name = "order_by"
732738 self .validate_schema_path (
733739 node_schema = node_schema ,
734740 path = order_by_path ,
735741 allowed_path_types = allowed_types ,
736- element_name = "order_by" ,
742+ element_name = element_name ,
737743 )
738744
739745 def validate_default_filters (self ) -> None :
@@ -778,36 +784,18 @@ def validate_human_friendly_id(self) -> None:
778784 if not node_schema .human_friendly_id :
779785 continue
780786
781- allowed_types = SchemaElementPathType .ATTR | SchemaElementPathType .REL_ONE_ATTR
782- for item in node_schema .human_friendly_id :
787+ allowed_types = SchemaElementPathType .ATTR_WITH_PROP | SchemaElementPathType .REL_ONE_MANDATORY_ATTR
788+ for hfid_path in node_schema .human_friendly_id :
783789 schema_path = self .validate_schema_path (
784790 node_schema = node_schema ,
785- path = item ,
791+ path = hfid_path ,
786792 allowed_path_types = allowed_types ,
787793 element_name = "human_friendly_id" ,
788794 )
789795
790796 if schema_path .is_type_attribute :
791- required_properties = tuple (schema_path .attribute_schema .get_class ().get_allowed_property_in_path ())
792- if schema_path .attribute_property_name not in required_properties :
793- raise ValueError (
794- f"{ node_schema .kind } HFID is invalid at attribute '{ schema_path .attribute_schema .name } ', it must end with one of the "
795- f"following properties: { ', ' .join (required_properties )} "
796- )
797797 hf_attr_names .add (schema_path .attribute_schema .name )
798798
799- if schema_path .is_type_relationship and schema_path .relationship_schema :
800- if schema_path .relationship_schema .optional and not (
801- schema_path .relationship_schema .name == "ip_namespace"
802- and isinstance (node_schema , NodeSchema )
803- and (node_schema .is_ip_address () or node_schema .is_ip_prefix )
804- ):
805- raise ValueError (
806- f"Only mandatory relationship of cardinality one can be used in human_friendly_id, "
807- f"{ schema_path .relationship_schema .name } is not mandatory on { schema_path .relationship_schema .kind } for "
808- f"{ node_schema .kind } . ({ item } )"
809- )
810-
811799 def validate_required_relationships (self ) -> None :
812800 reverse_dependency_map : dict [str , set [str ]] = {}
813801 for name in self .node_names + self .generic_names :
0 commit comments