Skip to content

Commit a3ce5bb

Browse files
committed
docs: add end-to-end registry deletion lifecycle snippet (#5360)
The existing registry deletion docs cover the CLI and individual Python SDK delete methods, but lack a single copy-pasteable example showing the full create -> verify -> delete -> confirm flow. - Add an 'End-to-end example' snippet to registry.md that lists a feature view, deletes it with delete_feature_view(), and lists again to confirm. - Add a unit test for FeatureView deletion via apply(objects_to_delete=..., partial=False) to guard the programmatic deletion path. Signed-off-by: goldokpa <okpagold@gmail.com>
1 parent 276b6df commit a3ce5bb

2 files changed

Lines changed: 78 additions & 2 deletions

File tree

docs/getting-started/components/registry.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ store._registry.delete_validation_reference("my_validation_reference", project=s
6969
When using `feast apply` via the CLI, you can also use the `objects_to_delete` parameter with `partial=False` to delete objects as part of the apply operation. However, this is less common and typically used in automated deployment scenarios.
7070
{% endhint %}
7171

72+
### End-to-end example
73+
74+
The following snippet shows the full lifecycle of deleting a feature view from the registry:
75+
76+
```python
77+
from feast import FeatureStore
78+
79+
store = FeatureStore(repo_path=".")
80+
81+
# 1. Verify the object exists before deletion
82+
print(store.list_batch_feature_views()) # shows my_feature_view
83+
84+
# 2. Delete the feature view
85+
store.delete_feature_view("my_feature_view")
86+
87+
# 3. Confirm it's gone
88+
print(store.list_batch_feature_views()) # my_feature_view no longer listed
89+
90+
# Trying to fetch it now raises FeatureViewNotFoundException
91+
# store.get_feature_view("my_feature_view")
92+
```
93+
94+
The same pattern works for other registry objects: list/verify the object, call the corresponding `delete_*` method, then list again to confirm the deletion.
95+
7296
## Accessing the registry from clients
7397

7498
Users can specify the registry through a `feature_store.yaml` config file, or programmatically. We often see teams

sdk/python/tests/unit/local_feast_tests/test_local_feature_store.py

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from feast.data_format import AvroFormat, ParquetFormat
1212
from feast.data_source import KafkaSource
1313
from feast.entity import Entity
14-
from feast.errors import ConflictingFeatureViewNames
14+
from feast.errors import ConflictingFeatureViewNames, FeatureViewNotFoundException
1515
from feast.feast_object import ALL_RESOURCE_TYPES
1616
from feast.feature_store import FeatureStore
1717
from feast.feature_view import DUMMY_ENTITY_ID, DUMMY_ENTITY_NAME, FeatureView
@@ -203,7 +203,7 @@ def test_apply_feature_view_with_inline_batch_source(
203203
) -> None:
204204
"""Test that a feature view and an inline batch source are both correctly applied."""
205205
with prep_file_source(df=simple_dataset_1, timestamp_field="ts_1") as file_source:
206-
entity = Entity(name="driver_entity", join_keys=["test_key"])
206+
entity = Entity(name="driver_entity", join_keys=["test_key"], value_type=ValueType.INT64)
207207
driver_fv = FeatureView(
208208
name="driver_fv",
209209
entities=[entity],
@@ -441,6 +441,58 @@ def test_apply_permissions(test_feature_store):
441441
test_feature_store.teardown()
442442

443443

444+
@pytest.mark.parametrize(
445+
"test_feature_store",
446+
[lazy_fixture("feature_store_with_local_registry")],
447+
)
448+
def test_apply_delete_feature_view(test_feature_store):
449+
"""Test that a feature view can be deleted using objects_to_delete with partial=False."""
450+
assert isinstance(test_feature_store, FeatureStore)
451+
452+
now = pd.Timestamp.utcnow().round("ms")
453+
dataframe_source = pd.DataFrame({
454+
"test_key": [1, 2, 1, 3, 3],
455+
"feature_value": [0.1, 0.2, 0.3, 4.0, 5.0],
456+
"ts_1": [
457+
now,
458+
now - pd.Timedelta(hours=4),
459+
now - pd.Timedelta(hours=3),
460+
now - pd.Timedelta(hours=2),
461+
now - pd.Timedelta(hours=1),
462+
],
463+
})
464+
465+
with prep_file_source(df=dataframe_source, timestamp_field="ts_1") as file_source:
466+
entity = Entity(name="driver_entity", join_keys=["test_key"], value_type=ValueType.INT64)
467+
driver_fv = FeatureView(
468+
name="driver_fv_to_delete",
469+
entities=[entity],
470+
schema=[Field(name="test_key", dtype=Int64)],
471+
source=file_source,
472+
)
473+
474+
# Register entity and feature view
475+
test_feature_store.apply([entity, driver_fv])
476+
477+
# Verify feature view exists
478+
fvs = test_feature_store.list_batch_feature_views()
479+
assert len(fvs) == 1
480+
assert fvs[0].name == driver_fv.name
481+
482+
# Delete the feature view using objects_to_delete
483+
test_feature_store.apply(objects=[], objects_to_delete=[driver_fv], partial=False)
484+
485+
# Verify feature view is deleted
486+
fvs = test_feature_store.list_batch_feature_views()
487+
assert len(fvs) == 0
488+
489+
# Verify get_feature_view raises FeatureViewNotFoundException
490+
with pytest.raises(FeatureViewNotFoundException):
491+
test_feature_store.get_feature_view(driver_fv.name)
492+
493+
test_feature_store.teardown()
494+
495+
444496
@pytest.mark.parametrize(
445497
"test_feature_store",
446498
[lazy_fixture("feature_store_with_local_registry")],

0 commit comments

Comments
 (0)