Skip to content

Commit 825e2fd

Browse files
committed
Fix bugs
Signed-off-by: Felix Wang <wangfelix98@gmail.com>
1 parent 5c9d281 commit 825e2fd

File tree

7 files changed

+63
-42
lines changed

7 files changed

+63
-42
lines changed

sdk/python/feast/base_feature_view.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def __eq__(self, other):
134134
if (
135135
self.name != other.name
136136
or sorted(self.features) != sorted(other.features)
137+
or self.projection != other.projection
137138
or self.description != other.description
138139
or self.tags != other.tags
139140
or self.owner != other.owner

sdk/python/feast/diff/registry_diff.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def extract_objects_for_keep_delete_update_add(
177177
FeastObjectType, List[Any]
178178
] = FeastObjectType.get_objects_from_registry(registry, current_project)
179179
registry_object_type_to_repo_contents: Dict[
180-
FeastObjectType, Set[Any]
180+
FeastObjectType, List[Any]
181181
] = FeastObjectType.get_objects_from_repo_contents(desired_repo_contents)
182182

183183
for object_type in FEAST_OBJECT_TYPES:

sdk/python/feast/feature_store.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -542,16 +542,16 @@ def _plan(
542542
"""
543543
# Validate and run inference on all the objects to be registered.
544544
self._validate_all_feature_views(
545-
list(desired_repo_contents.feature_views),
546-
list(desired_repo_contents.on_demand_feature_views),
547-
list(desired_repo_contents.request_feature_views),
545+
desired_repo_contents.feature_views,
546+
desired_repo_contents.on_demand_feature_views,
547+
desired_repo_contents.request_feature_views,
548548
)
549-
_validate_data_sources(list(desired_repo_contents.data_sources))
549+
_validate_data_sources(desired_repo_contents.data_sources)
550550
self._make_inferences(
551-
list(desired_repo_contents.data_sources),
552-
list(desired_repo_contents.entities),
553-
list(desired_repo_contents.feature_views),
554-
list(desired_repo_contents.on_demand_feature_views),
551+
desired_repo_contents.data_sources,
552+
desired_repo_contents.entities,
553+
desired_repo_contents.feature_views,
554+
desired_repo_contents.on_demand_feature_views,
555555
)
556556

557557
# Compute the desired difference between the current objects in the registry and

sdk/python/feast/registry.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from enum import Enum
1919
from pathlib import Path
2020
from threading import Lock
21-
from typing import Any, Dict, List, Optional, Set
21+
from typing import Any, Dict, List, Optional
2222
from urllib.parse import urlparse
2323

2424
import dill
@@ -98,7 +98,7 @@ def get_objects_from_registry(
9898
@staticmethod
9999
def get_objects_from_repo_contents(
100100
repo_contents: RepoContents,
101-
) -> Dict["FeastObjectType", Set[Any]]:
101+
) -> Dict["FeastObjectType", List[Any]]:
102102
return {
103103
FeastObjectType.DATA_SOURCE: repo_contents.data_sources,
104104
FeastObjectType.ENTITY: repo_contents.entities,

sdk/python/feast/repo_contents.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from typing import NamedTuple, Set
14+
from typing import List, NamedTuple
1515

1616
from feast.data_source import DataSource
1717
from feast.entity import Entity
@@ -27,12 +27,12 @@ class RepoContents(NamedTuple):
2727
Represents the objects in a Feast feature repo.
2828
"""
2929

30-
data_sources: Set[DataSource]
31-
feature_views: Set[FeatureView]
32-
on_demand_feature_views: Set[OnDemandFeatureView]
33-
request_feature_views: Set[RequestFeatureView]
34-
entities: Set[Entity]
35-
feature_services: Set[FeatureService]
30+
data_sources: List[DataSource]
31+
feature_views: List[FeatureView]
32+
on_demand_feature_views: List[OnDemandFeatureView]
33+
request_feature_views: List[RequestFeatureView]
34+
entities: List[Entity]
35+
feature_services: List[FeatureService]
3636

3737
def to_registry_proto(self) -> RegistryProto:
3838
registry_proto = RegistryProto()

sdk/python/feast/repo_operations.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,36 +94,56 @@ def get_repo_files(repo_root: Path) -> List[Path]:
9494

9595

9696
def parse_repo(repo_root: Path) -> RepoContents:
97-
"""Collect feature table definitions from feature repo"""
97+
"""
98+
Collects unique Feast object definitions from the given feature repo.
99+
100+
Specifically, if an object foo has already been added, bar will still be added if
101+
(bar == foo), but not if (bar is foo). This ensures that import statements will
102+
not result in duplicates, but defining two equal objects will.
103+
"""
98104
res = RepoContents(
99-
data_sources=set(),
100-
entities=set(),
101-
feature_views=set(),
102-
feature_services=set(),
103-
on_demand_feature_views=set(),
104-
request_feature_views=set(),
105+
data_sources=[],
106+
entities=[],
107+
feature_views=[],
108+
feature_services=[],
109+
on_demand_feature_views=[],
110+
request_feature_views=[],
105111
)
106112

107113
for repo_file in get_repo_files(repo_root):
108114
module_path = py_path_to_module(repo_file, repo_root)
109115
module = importlib.import_module(module_path)
110116
for attr_name in dir(module):
111117
obj = getattr(module, attr_name)
112-
if isinstance(obj, DataSource):
113-
res.data_sources.add(obj)
114-
if isinstance(obj, FeatureView):
115-
res.feature_views.add(obj)
116-
if isinstance(obj.stream_source, PushSource):
117-
res.data_sources.add(obj.stream_source.batch_source)
118-
elif isinstance(obj, Entity):
119-
res.entities.add(obj)
120-
elif isinstance(obj, FeatureService):
121-
res.feature_services.add(obj)
122-
elif isinstance(obj, OnDemandFeatureView):
123-
res.on_demand_feature_views.add(obj)
124-
elif isinstance(obj, RequestFeatureView):
125-
res.request_feature_views.add(obj)
126-
res.entities.add(DUMMY_ENTITY)
118+
if isinstance(obj, DataSource) and not any(
119+
(obj is ds) for ds in res.data_sources
120+
):
121+
res.data_sources.append(obj)
122+
if isinstance(obj, FeatureView) and not any(
123+
(obj is fv) for fv in res.feature_views
124+
):
125+
res.feature_views.append(obj)
126+
if isinstance(obj.stream_source, PushSource) and not any(
127+
(obj is ds) for ds in res.data_sources
128+
):
129+
res.data_sources.append(obj.stream_source.batch_source)
130+
elif isinstance(obj, Entity) and not any(
131+
(obj is entity) for entity in res.entities
132+
):
133+
res.entities.append(obj)
134+
elif isinstance(obj, FeatureService) and not any(
135+
(obj is fs) for fs in res.feature_services
136+
):
137+
res.feature_services.append(obj)
138+
elif isinstance(obj, OnDemandFeatureView) and not any(
139+
(obj is odfv) for odfv in res.on_demand_feature_views
140+
):
141+
res.on_demand_feature_views.append(obj)
142+
elif isinstance(obj, RequestFeatureView) and not any(
143+
(obj is rfv) for rfv in res.request_feature_views
144+
):
145+
res.request_feature_views.append(obj)
146+
res.entities.append(DUMMY_ENTITY)
127147
return res
128148

129149

sdk/python/tests/example_repos/example_feature_repo_with_duplicated_featureview_names.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
name="driver_hourly_stats", # Intentionally use the same FeatureView name
1111
entities=["driver_id"],
1212
online=False,
13-
batch_source=driver_hourly_stats,
13+
source=driver_hourly_stats,
1414
ttl=timedelta(days=1),
1515
tags={},
1616
)
@@ -19,7 +19,7 @@
1919
name="driver_hourly_stats", # Intentionally use the same FeatureView name
2020
entities=["driver_id"],
2121
online=False,
22-
batch_source=driver_hourly_stats,
22+
source=driver_hourly_stats,
2323
ttl=timedelta(days=1),
2424
tags={},
2525
)

0 commit comments

Comments
 (0)