GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||
GeezerVison is showing github.com — feat: Lance as an engine-agnostic, catalog-backed, version-pinned data source · Issue #6899 · feast-dev/feast Open Labels kind/featureNew feature or requestNew feature or request DescriptionSummaryFeast has no Lance support today — no issue or PR references it. This proposes Filing it as one issue because those three are only separable on paper: an embedding source is useless without a version pin, a declared vector schema, and a choice of execution engine. Why this is not #1494 / #1533Format-specific sources have a poor record here — #1494 (Hudi) was closed wontfix, #1533 (Delta) has been open since 2021. So this is deliberately not "add another format". In #6499, @ntkathole proposed moving catalog connection config onto the
Proposal
|
| Path | Engine | Use |
|---|---|---|
| Native | pylance + DataFusion/DuckDB |
local dev, CI, notebooks, eval-set construction |
| Spark | lance-spark |
existing batch/GPU clusters |
The read-path half is already solved: HybridOfflineStore (#5541, shipped in 0.51.0) routes by data source type, so both stores can coexist in one project.
The remaining gap is #5330 — batch_engine / batch_configs on FeatureView are still placeholders, so a project cannot choose the engine per FeatureView. An embedding pipeline needs exactly that: Spark for generation, native for interactive retrieval, one project. #6359 looks like the structural prerequisite, since the offline-store retrieval path currently bypasses the compute engine.
Precedent for one source across engines: FileSource is served by both the Dask and DuckDB offline stores.
@jfw-ppi asked whether the response schema would stay FeatureView-defined rather than varying by store or snapshot. Proposed:
FeatureView schema is the contract. A pinned version selects data, never shape.Related, and an argument for validating rather than trusting declarations: in Field.__eq__ the vector_index and vector_search_metric comparisons are currently commented out, so only vector_length participates in equality:
or self.vector_length != other.vector_length # or self.vector_index != other.vector_index # or self.vector_search_metric != other.vector_search_metric
A metric change from COSINE to L2 is therefore invisible to feast apply / plan. Happy to split that out into its own bug if preferred.
This assumes #5652's direction: vector config belongs to the feature definition, not global online_store config. The Field attributes already exist, but online stores still read dimension and metric from global config, so two feature views with different dimensions cannot coexist in one project.
Not proposing Lance as an online store. Lance is a format plus indexes, not a low-latency KV service, and its write path is columnar while online_write_batch is row-oriented proto. Offline / retrieval axis only.
LanceSource + native (pylance) offline store, path-based only — landable without waiting on feat: Extend Feast's DataSource to natively support Iceberg REST Catalog-backed tables #6499version / tag pinning + schema validation (Supporting snapshot based time travel for Feast #5782)LanceSourceStatus, plus a correction to the original text.
Correction. The body says it is "cheaper to settle before IcebergRestCatalogSource lands than after". That was wrong when I wrote it — the work from #6499 had already merged. sdk/python/feast/infra/data_sources/contrib/iceberg_catalog/ exists on master with IcebergSource, UnityCatalogSource, IcebergRestClient, and both DuckDB and Spark tests. Apologies for the misleading framing.
Reading the merged code changes the argument rather than weakening it. IcebergSource carries catalog configuration flattened onto the source — catalog_type, catalog_name, endpoint, catalog_properties: Dict[str, str], token_env_var, credential_vending — and constructs its client inside get_catalog_client() with an if/elif on catalog_type. A second catalog-backed format either duplicates all of that or motivates extracting it. There is also already a UnityCatalogSource alongside IcebergSource, so the naming is drifting between two axes: one source named for a catalog, one for a format.
What landed. #6925 (1196e2233) added LanceFormat to the existing TableFormat abstraction from #5650 rather than adding a new source, which turned out to be the better fit:
catalog / namespace addressing plus an optional pin via version or tagSparkSource unchanged, because it already drives its reader from table_format.format_type.value and table_format.propertiesversion >= 1 enforced so the Python and proto semantics agree, since the proto treats 0 as unsetSo the LanceSource sketch in the body is superseded — LanceFormat is the shape that merged.
Still open. The format descriptor exists; there is no Lance reader yet. The remaining scope from this issue:
pylance read path, so a Lance source can be served without Spark. This is the real test of whether the DataSource/offline-store split is engine-agnostic rather than Spark-agnostic in name only.catalog_type/catalog_properties question above settled. Worth noting Apache Polaris serves Lance through its generic-tables API, on a different path from its Iceberg API, so the two cannot share a source even though they can share a catalog.FeatureView should fail explicitly. That is the open question @jfw-ppi raised on Supporting snapshot based time travel for Feast #5782.Keeping this open for 1-3. Happy to split them out if that is easier to track.