Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0800f13
feat: Implement Databricks Unity Catalog offline store integration
falloficaruss Jun 14, 2026
3a4edcd
Merge branch 'master' into feat/databricks-uc-provider
falloficaruss Jun 16, 2026
664107f
fix: Initialize Databricks session in DatabricksUCOfflineStore valida…
falloficaruss Jun 16, 2026
3b30044
fix: Fix MyPy errors by asserting SparkSession is not None
falloficaruss Jun 21, 2026
6059c9d
Merge branch 'master' into feat/databricks-uc-provider
falloficaruss Jun 21, 2026
faa0675
feat: Register FeatureViews as Unity Catalog feature tables on feast …
falloficaruss Jun 27, 2026
327228c
fix: Rename schema to uc_schema, add missing type mappings, add tests…
falloficaruss Jun 28, 2026
147a572
Merge branch 'master' into feat/databricks-uc-registration
falloficaruss Jun 28, 2026
3d0c8ca
Merge branch 'master' into feat/databricks-uc-registration
falloficaruss Jul 1, 2026
16870f3
feat: Refactor L2 to build on Iceberg REST Catalog instead of Databri…
falloficaruss Jul 1, 2026
4f41ccf
feat: Implement UC-backed materialization via compute engine hooks (L3)
falloficaruss Jun 28, 2026
c2a0d27
feat: Add click-to-zoom lightbox for blog post images (#6575)
franciscojavierarceo Jul 1, 2026
9446524
fix: configure FIPS-compliant gRPC cipher suites for offline server
aniketpalu Jul 1, 2026
5ce0cf7
feat: Add OnlineStore for Aerospike (#6532)
vkagamlyk Jul 2, 2026
267abdf
fix: add debug logging for FIPS mode detection fallback
aniketpalu Jul 2, 2026
4193c0d
fix: Unblock nightly UI build (#6570)
franciscojavierarceo Jul 3, 2026
386599e
feat: Implement Iceberg REST Catalog-backed materialization (L3)
falloficaruss Jul 3, 2026
d08c7c4
Merge branch 'master' into feat/databricks-uc-materialization
falloficaruss Jul 3, 2026
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
70 changes: 70 additions & 0 deletions sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,10 @@ def _apply_diffs(
# Emit OpenLineage events for applied objects
self._emit_openlineage_apply_diffs(registry_diff)

# Register feature views as Unity Catalog feature tables (if using
# the databricks_uc offline store)
self._register_uc_feature_tables_from_diffs(registry_diff)

# Emit MLflow events for applied objects (Phase 7)
self._mlflow_log_apply_diffs(registry_diff)

Expand Down Expand Up @@ -1637,6 +1641,10 @@ def apply(
# Emit OpenLineage events for applied objects
self._emit_openlineage_apply(objects)

# Register feature views as Unity Catalog feature tables (if using
# the databricks_uc offline store)
self._register_uc_feature_tables_legacy(objects)

# Emit MLflow events for applied objects (Phase 7)
self._mlflow_log_apply(objects)

Expand Down Expand Up @@ -1665,6 +1673,68 @@ def _emit_openlineage_apply(self, objects: List[Any]):
except Exception as e:
warnings.warn(f"Failed to emit OpenLineage apply events: {e}")

# ------------------------------------------------------------------ #
# Unity Catalog feature table registration hooks
# ------------------------------------------------------------------ #

def _register_uc_feature_tables_from_diffs(
self, registry_diff: RegistryDiff
) -> None:
"""Register applied feature views as UC feature tables.

Only active when the offline store is ``databricks_uc`` and
``uc_registration.enabled`` is True.
"""
from feast.infra.offline_stores.contrib.spark_offline_store.databricks_uc import (
DatabricksUCOfflineStoreConfig,
)
from feast.infra.offline_stores.iceberg.registration import (
register_uc_feature_tables,
)

if not isinstance(self.config.offline_store, DatabricksUCOfflineStoreConfig):
return

uc_config = self.config.offline_store.uc_registration
if uc_config is None or not uc_config.enabled:
return

fvs = [
d.new_feast_object
for d in registry_diff.feast_object_diffs
if d.new_feast_object and isinstance(d.new_feast_object, FeatureView)
]
if not fvs:
return

register_uc_feature_tables(self.config.offline_store.catalog, fvs, self.project)

def _register_uc_feature_tables_legacy(self, objects: List[Any]) -> None:
"""Register feature views as UC feature tables (legacy apply path).

Only active when the offline store is ``databricks_uc`` and
``uc_registration.enabled`` is True.
"""
from feast.infra.offline_stores.contrib.spark_offline_store.databricks_uc import (
DatabricksUCOfflineStoreConfig,
)
from feast.infra.offline_stores.iceberg.registration import (
register_uc_feature_tables,
)

if not isinstance(self.config.offline_store, DatabricksUCOfflineStoreConfig):
return

uc_config = self.config.offline_store.uc_registration
if uc_config is None or not uc_config.enabled:
return

fvs = [obj for obj in objects if isinstance(obj, FeatureView)]
if not fvs:
return

register_uc_feature_tables(self.config.offline_store.catalog, fvs, self.project)

def teardown(self):
"""Tears down all local and cloud resources for the feature store."""
tables: List[BaseFeatureView] = []
Expand Down
14 changes: 14 additions & 0 deletions sdk/python/feast/infra/compute_engines/local/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,4 +407,18 @@ def execute(self, context: ExecutionContext) -> ArrowTableValue:
progress=lambda x: None,
)

# UC-backed materialization hook (Phase L3)
catalog_config = getattr(context.repo_config.offline_store, "catalog", None)
if catalog_config is not None:
from feast.infra.offline_stores.iceberg.registration import (
write_uc_materialized_data,
)

write_uc_materialized_data(
catalog_config=catalog_config,
fv=self.feature_view,
df=input_table,
project=context.repo_config.project,
)

return output
14 changes: 14 additions & 0 deletions sdk/python/feast/infra/compute_engines/spark/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,20 @@ def execute(self, context: ExecutionContext) -> DAGValue:
)
spark_df.write.format(file_format).mode("append").save(dest_path)

# UC-backed materialization hook (Phase L3)
catalog_config = getattr(context.repo_config.offline_store, "catalog", None)
if catalog_config is not None:
from feast.infra.offline_stores.iceberg.registration import (
write_uc_materialized_data,
)

write_uc_materialized_data(
catalog_config=catalog_config,
fv=self.feature_view,
df=spark_df,
project=context.repo_config.project,
)

return DAGValue(
data=spark_df,
format=DAGFormat.SPARK,
Expand Down
Loading