Skip to content
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

refactor: Delete unnecessary errors.go file #2392

Merged
merged 3 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions go/internal/feast/errors.go

This file was deleted.

46 changes: 27 additions & 19 deletions go/internal/feast/featurestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,52 +401,51 @@ func (fs *FeatureStore) validateEntityValues(joinKeyValues map[string]*types.Rep
}

func (fs *FeatureStore) validateFeatureRefs(featureRefs []string, fullFeatureNames bool) error {
collidedFeatureRefs := make(map[string]int)
featureRefCounter := make(map[string]int)
if fullFeatureNames {
for _, featureRef := range featureRefs {
collidedFeatureRefs[featureRef] += 1
featureRefCounter[featureRef]++
}
for featureName, occurrences := range collidedFeatureRefs {
for featureName, occurrences := range featureRefCounter {
if occurrences == 1 {
delete(collidedFeatureRefs, featureName)
delete(featureRefCounter, featureName)
}
}
if len(collidedFeatureRefs) >= 1 {
collidedFeatureRefList := make([]string, len(collidedFeatureRefs))
if len(featureRefCounter) >= 1 {
collidedFeatureRefs := make([]string, len(featureRefCounter))
index := 0
for featureName := range collidedFeatureRefs {
collidedFeatureRefList[index] = featureName
index += 1
for collidedFeatureRef := range featureRefCounter {
collidedFeatureRefs[index] = collidedFeatureRef
index++
}
return NewFeatureNameCollisionError(collidedFeatureRefList, fullFeatureNames)
return featureNameCollisionError{collidedFeatureRefs, fullFeatureNames}
}
} else {
for _, featureRef := range featureRefs {
_, featureName, err := parseFeatureReference(featureRef)
if err != nil {
return err
}
collidedFeatureRefs[featureName] += 1
featureRefCounter[featureName]++
}

for featureName, occurrences := range collidedFeatureRefs {
for featureName, occurrences := range featureRefCounter {
if occurrences == 1 {
delete(collidedFeatureRefs, featureName)
delete(featureRefCounter, featureName)
}
}
if len(collidedFeatureRefs) >= 1 {
collidedFeatureRefList := make([]string, 0)
if len(featureRefCounter) >= 1 {
collidedFeatureRefs := make([]string, 0)
for _, featureRef := range featureRefs {
_, featureName, err := parseFeatureReference(featureRef)
if err != nil {
return err
}
if _, ok := collidedFeatureRefs[featureName]; ok {
collidedFeatureRefList = append(collidedFeatureRefList, featureRef)
if _, ok := featureRefCounter[featureName]; ok {
collidedFeatureRefs = append(collidedFeatureRefs, featureRef)
}

}
return errors.New(fmt.Sprintf("featureNameCollisionError: %s; %t", strings.Join(collidedFeatureRefList, ", "), fullFeatureNames))
return featureNameCollisionError{collidedFeatureRefs, fullFeatureNames}
}
}
return nil
Expand Down Expand Up @@ -858,3 +857,12 @@ func getFeatureResponseMeta(featureNameAlias string, featureName string, fullFea
return featureName
}
}

type featureNameCollisionError struct {
featureRefCollisions []string
fullFeatureNames bool
}

func (e featureNameCollisionError) Error() string {
return fmt.Sprintf("featureNameCollisionError: %s; %t", strings.Join(e.featureRefCollisions, ", "), e.fullFeatureNames)
}
40 changes: 25 additions & 15 deletions sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,12 +782,12 @@ def get_historical_features(
columns (e.g., customer_id, driver_id) on which features need to be joined, as well as a event_timestamp
column used to ensure point-in-time correctness. Either a Pandas DataFrame can be provided or a string
SQL query. The query must be of a format supported by the configured offline store (e.g., BigQuery)
features: A list of features, that should be retrieved from the offline store.
Either a list of string feature references can be provided or a FeatureService object.
Feature references are of the format "feature_view:feature", e.g., "customer_fv:daily_transactions".
full_feature_names: A boolean that provides the option to add the feature view prefixes to the feature names,
changing them from the format "feature" to "feature_view__feature" (e.g., "daily_transactions" changes to
"customer_fv__daily_transactions"). By default, this value is set to False.
features: The list of features that should be retrieved from the offline store. These features can be
specified either as a list of string feature references or as a feature service. String feature
references must have format "feature_view:feature", e.g. "customer_fv:daily_transactions".
full_feature_names: If True, feature names will be prefixed with the corresponding feature view name,
changing them from the format "feature" to "feature_view__feature" (e.g. "daily_transactions"
changes to "customer_fv__daily_transactions").

Returns:
RetrievalJob which can be used to materialize the results.
Expand Down Expand Up @@ -820,7 +820,6 @@ def get_historical_features(
... )
>>> feature_data = retrieval_job.to_df()
"""

_feature_refs = self._get_features(features)
(
all_feature_views,
Expand Down Expand Up @@ -1192,12 +1191,13 @@ def get_online_features(
infinity (cache forever).

Args:
features: List of feature references that will be returned for each entity.
Each feature reference should have the following format:
"feature_view:feature" where "feature_view" & "feature" refer to
the Feature and FeatureView names respectively.
Only the feature name is required.
features: The list of features that should be retrieved from the online store. These features can be
specified either as a list of string feature references or as a feature service. String feature
references must have format "feature_view:feature", e.g. "customer_fv:daily_transactions".
entity_rows: A list of dictionaries where each key-value is an entity-name, entity-value pair.
full_feature_names: If True, feature names will be prefixed with the corresponding feature view name,
changing them from the format "feature" to "feature_view__feature" (e.g. "daily_transactions"
changes to "customer_fv__daily_transactions").

Returns:
OnlineResponse containing the feature data in records.
Expand Down Expand Up @@ -1876,16 +1876,26 @@ def _validate_entity_values(join_key_values: Dict[str, List[Value]]):


def _validate_feature_refs(feature_refs: List[str], full_feature_names: bool = False):
"""
Validates that there are no collisions among the feature references.

Args:
feature_refs: List of feature references to validate. Feature references must have format
"feature_view:feature", e.g. "customer_fv:daily_transactions".
full_feature_names: If True, the full feature references are compared for collisions; if False,
only the feature names are compared.

Raises:
FeatureNameCollisionError: There is a collision among the feature references.
"""
collided_feature_refs = []

if full_feature_names:
collided_feature_refs = [
ref for ref, occurrences in Counter(feature_refs).items() if occurrences > 1
]
else:
feature_names = [
ref.split(":")[1] if ":" in ref else ref for ref in feature_refs
]
feature_names = [ref.split(":")[1] for ref in feature_refs]
collided_feature_names = [
ref
for ref, occurrences in Counter(feature_names).items()
Expand Down