From 739703c9b61896277adc3fcc16d44f5c0f3fa1df Mon Sep 17 00:00:00 2001 From: Sanskar Singh Date: Wed, 5 Aug 2026 20:56:31 +0530 Subject: [PATCH] feat: Add hybrid to ValidOfflineStoreDBStorePersistenceTypes for HybridOfflineStore support The Feast SDK supports HybridOfflineStore, which routes offline operations to different backends based on each FeatureView's batch_source, but the operator's FeatureStore CRD did not allow type: hybrid in the offline store persistence enum, blocking configuration via the CR. Mirrors the online store fix in #5810: - Register hybrid in OFFLINE_STORE_CLASS_FOR_TYPE so the type resolves to HybridOfflineStore (the SDK map previously had this only for the online store). - Add hybrid to the offline DB store enum and ValidOfflineStoreDBStorePersistenceTypes in both api/v1 and api/v1alpha1, and regenerate the CRD manifests (config/crd/bases, dist/install.yaml, bundle/manifests). - Update the offline hybrid doc to use the short type: hybrid form. Fixes #6701 Signed-off-by: Sanskar Singh --- .secrets.baseline | 4 ++-- docs/reference/offline-stores/hybrid.md | 2 +- infra/feast-operator/api/v1/featurestore_types.go | 3 ++- infra/feast-operator/api/v1alpha1/featurestore_types.go | 3 ++- .../bundle/manifests/feast.dev_featurestores.yaml | 4 ++++ .../config/crd/bases/feast.dev_featurestores.yaml | 4 ++++ infra/feast-operator/dist/install.yaml | 4 ++++ sdk/python/feast/repo_config.py | 1 + 8 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 62d7fd33f37..1abcbee1153 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -957,7 +957,7 @@ "filename": "infra/feast-operator/api/v1/featurestore_types.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 958 + "line_number": 959 } ], "infra/feast-operator/api/v1/zz_generated.deepcopy.go": [ @@ -989,7 +989,7 @@ "filename": "infra/feast-operator/api/v1alpha1/featurestore_types.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 663 + "line_number": 664 } ], "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go": [ diff --git a/docs/reference/offline-stores/hybrid.md b/docs/reference/offline-stores/hybrid.md index a10ed66fd2c..38adb1820e0 100644 --- a/docs/reference/offline-stores/hybrid.md +++ b/docs/reference/offline-stores/hybrid.md @@ -18,7 +18,7 @@ project: my_feature_repo registry: data/registry.db provider: local offline_store: - type: hybrid_offline_store.HybridOfflineStore + type: hybrid offline_stores: - type: spark conf: diff --git a/infra/feast-operator/api/v1/featurestore_types.go b/infra/feast-operator/api/v1/featurestore_types.go index 3372e74f63a..247f1dc3f87 100644 --- a/infra/feast-operator/api/v1/featurestore_types.go +++ b/infra/feast-operator/api/v1/featurestore_types.go @@ -528,7 +528,7 @@ var ValidOfflineStoreFilePersistenceTypes = []string{ // OfflineStoreDBStorePersistence configures the DB store persistence for the offline store service type OfflineStoreDBStorePersistence struct { // Type of the persistence type you want to use. - // +kubebuilder:validation:Enum=snowflake.offline;bigquery;redshift;spark;postgres;trino;athena;mssql;couchbase.offline;clickhouse;ray;oracle + // +kubebuilder:validation:Enum=snowflake.offline;bigquery;redshift;spark;postgres;trino;athena;mssql;couchbase.offline;clickhouse;ray;oracle;hybrid Type string `json:"type"` // Data store parameters should be placed as-is from the "feature_store.yaml" under the secret key. "registry_type" & "type" fields should be removed. SecretRef corev1.LocalObjectReference `json:"secretRef"` @@ -549,6 +549,7 @@ var ValidOfflineStoreDBStorePersistenceTypes = []string{ "clickhouse", "ray", "oracle", + "hybrid", } // OnlineStore configures the online store service diff --git a/infra/feast-operator/api/v1alpha1/featurestore_types.go b/infra/feast-operator/api/v1alpha1/featurestore_types.go index 8ccde377e77..985a6887316 100644 --- a/infra/feast-operator/api/v1alpha1/featurestore_types.go +++ b/infra/feast-operator/api/v1alpha1/featurestore_types.go @@ -337,7 +337,7 @@ var ValidOfflineStoreFilePersistenceTypes = []string{ // OfflineStoreDBStorePersistence configures the DB store persistence for the offline store service type OfflineStoreDBStorePersistence struct { // Type of the persistence type you want to use. - // +kubebuilder:validation:Enum=snowflake.offline;bigquery;redshift;spark;postgres;trino;athena;mssql;couchbase.offline;clickhouse;ray + // +kubebuilder:validation:Enum=snowflake.offline;bigquery;redshift;spark;postgres;trino;athena;mssql;couchbase.offline;clickhouse;ray;hybrid Type string `json:"type"` // Data store parameters should be placed as-is from the "feature_store.yaml" under the secret key. "registry_type" & "type" fields should be removed. SecretRef corev1.LocalObjectReference `json:"secretRef"` @@ -357,6 +357,7 @@ var ValidOfflineStoreDBStorePersistenceTypes = []string{ "couchbase.offline", "clickhouse", "ray", + "hybrid", } // OnlineStore configures the online store service diff --git a/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml b/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml index 0ab08afef51..4ac3ed65e1b 100644 --- a/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml +++ b/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml @@ -1881,6 +1881,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -8211,6 +8212,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -13771,6 +13773,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef @@ -18292,6 +18295,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef diff --git a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml index 8184906e14d..608a63a5b9e 100644 --- a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml +++ b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml @@ -1881,6 +1881,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -8211,6 +8212,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -13771,6 +13773,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef @@ -18292,6 +18295,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef diff --git a/infra/feast-operator/dist/install.yaml b/infra/feast-operator/dist/install.yaml index be85a29a7b2..94490b531fa 100644 --- a/infra/feast-operator/dist/install.yaml +++ b/infra/feast-operator/dist/install.yaml @@ -1889,6 +1889,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -8219,6 +8220,7 @@ spec: - clickhouse - ray - oracle + - hybrid type: string required: - secretRef @@ -13779,6 +13781,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef @@ -18300,6 +18303,7 @@ spec: - couchbase.offline - clickhouse - ray + - hybrid type: string required: - secretRef diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index 775a62aab57..5a975f0a1c2 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -108,6 +108,7 @@ "clickhouse": "feast.infra.offline_stores.contrib.clickhouse_offline_store.clickhouse.ClickhouseOfflineStore", "ray": "feast.infra.offline_stores.contrib.ray_offline_store.ray.RayOfflineStore", "oracle": "feast.infra.offline_stores.contrib.oracle_offline_store.oracle.OracleOfflineStore", + "hybrid": "feast.infra.offline_stores.hybrid_offline_store.HybridOfflineStore", } FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE = {