Skip to content
Open
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
24 changes: 24 additions & 0 deletions docs/getting-started/components/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ store._registry.delete_validation_reference("my_validation_reference", project=s
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.
{% endhint %}

### End-to-end example

The following snippet shows the full lifecycle of deleting a feature view from the registry:

```python
from feast import FeatureStore

store = FeatureStore(repo_path=".")

# 1. Verify the object exists before deletion
print(store.list_batch_feature_views()) # shows my_feature_view

# 2. Delete the feature view
store.delete_feature_view("my_feature_view")

# 3. Confirm it's gone
print(store.list_batch_feature_views()) # my_feature_view no longer listed

# Trying to fetch it now raises FeatureViewNotFoundException
# store.get_feature_view("my_feature_view")
```

The same pattern works for other registry objects: list/verify the object, call the corresponding `delete_*` method, then list again to confirm the deletion.

## Accessing the registry from clients

Users can specify the registry through a `feature_store.yaml` config file, or programmatically. We often see teams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from feast.data_format import AvroFormat, ParquetFormat
from feast.data_source import KafkaSource
from feast.entity import Entity
from feast.errors import ConflictingFeatureViewNames
from feast.errors import ConflictingFeatureViewNames, FeatureViewNotFoundException
from feast.feast_object import ALL_RESOURCE_TYPES
from feast.feature_store import FeatureStore
from feast.feature_view import DUMMY_ENTITY_ID, DUMMY_ENTITY_NAME, FeatureView
Expand Down Expand Up @@ -441,6 +441,64 @@ def test_apply_permissions(test_feature_store):
test_feature_store.teardown()


@pytest.mark.parametrize(
"test_feature_store",
[lazy_fixture("feature_store_with_local_registry")],
)
def test_apply_delete_feature_view(test_feature_store):
"""Test that a feature view can be deleted using objects_to_delete with partial=False."""
assert isinstance(test_feature_store, FeatureStore)

now = pd.Timestamp.utcnow().round("ms")
dataframe_source = pd.DataFrame(
{
"test_key": [1, 2, 1, 3, 3],
"feature_value": [0.1, 0.2, 0.3, 4.0, 5.0],
"ts_1": [
now,
now - pd.Timedelta(hours=4),
now - pd.Timedelta(hours=3),
now - pd.Timedelta(hours=2),
now - pd.Timedelta(hours=1),
],
}
)

with prep_file_source(df=dataframe_source, timestamp_field="ts_1") as file_source:
entity = Entity(
name="driver_entity", join_keys=["test_key"], value_type=ValueType.INT64
)
driver_fv = FeatureView(
name="driver_fv_to_delete",
entities=[entity],
schema=[Field(name="test_key", dtype=Int64)],
source=file_source,
)

# Register entity and feature view
test_feature_store.apply([entity, driver_fv])

# Verify feature view exists
fvs = test_feature_store.list_batch_feature_views()
assert len(fvs) == 1
assert fvs[0].name == driver_fv.name

# Delete the feature view using objects_to_delete
test_feature_store.apply(
objects=[], objects_to_delete=[driver_fv], partial=False
)

# Verify feature view is deleted
fvs = test_feature_store.list_batch_feature_views()
assert len(fvs) == 0

# Verify get_feature_view raises FeatureViewNotFoundException
with pytest.raises(FeatureViewNotFoundException):
test_feature_store.get_feature_view(driver_fv.name)

test_feature_store.teardown()


@pytest.mark.parametrize(
"test_feature_store",
[lazy_fixture("feature_store_with_local_registry")],
Expand Down