Verify feature views have case-insensitively unique names across all types. This validates that no two feature views (of any type: FeatureView, StreamFeatureView, OnDemandFeatureView) share the same case-insensitive name. This is critical because get_online_features uses get_any_feature
(feature_views: List[BaseFeatureView])
| 4275 | |
| 4276 | |
| 4277 | def _validate_feature_views(feature_views: List[BaseFeatureView]): |
| 4278 | """Verify feature views have case-insensitively unique names across all types. |
| 4279 | |
| 4280 | This validates that no two feature views (of any type: FeatureView, |
| 4281 | StreamFeatureView, OnDemandFeatureView) share the same case-insensitive name. |
| 4282 | This is critical because get_online_features uses get_any_feature_view which |
| 4283 | resolves names in a fixed order, potentially returning the wrong feature view. |
| 4284 | """ |
| 4285 | fv_by_name: Dict[str, BaseFeatureView] = {} |
| 4286 | for fv in feature_views: |
| 4287 | case_insensitive_fv_name = fv.name.lower() |
| 4288 | if case_insensitive_fv_name in fv_by_name: |
| 4289 | existing_fv = fv_by_name[case_insensitive_fv_name] |
| 4290 | raise ConflictingFeatureViewNames( |
| 4291 | fv.name, |
| 4292 | existing_type=type(existing_fv).__name__, |
| 4293 | new_type=type(fv).__name__, |
| 4294 | ) |
| 4295 | else: |
| 4296 | fv_by_name[case_insensitive_fv_name] = fv |
| 4297 | |
| 4298 | |
| 4299 | def _validate_data_sources(data_sources: List[DataSource]): |