Skip to content

Bug: UserWarning when passing FeatureService object to both apply() and get_online_features() - Caused by difference in FeatureViewProjection.from_proto() and FeatureViewProjection.from_definition() #4030

@job-almekinders

Description

@job-almekinders

Context

If a FeatureService object is created and is being passed to both the apply() and the get_online_features() method, the following user warning is thrown:

UserWarning: The FeatureService object that has been passed in as an argument is inconsistent with the version from the registry. Potentially a newer version of the FeatureService has been applied to the registry.

This is caused by a bug in the creation/retrieval of feature_view_projections, which is an attribute of FeatureService. An empty string is set to the name_alias value of FeatureViewProjection when calling from_proto. However, when creating the FeatureViewProjection by creating a FeatureService object (using the default value) name_alias is set to None, because it is created with FeatureViewProjection.from_definition().

The warning is raised here, because the feature_service_from_registry has the empty string value for the underlying FeatureViewProjection.name_alias object, while the for _features the underlying FeatureViewProjection.name_alias is valued None.

Expected Behavior

I would expect that if a FeatureViewProjection encapsulated within a FeatureService has a None value for the name_alias attribute when being stored in the feature store, that it would also load with the same None value when calling FeatureViewProjection.from_proto().

Then the comparison should also not fail, and the warning should not be thrown.

Current Behavior

The FeatureViewProjection is loaded with an empty string for the value name_alias when FeatureViewProjection.from_proto() is called.

This causes the. comparison to fail, and the warning to be thrown.

Steps to reproduce

docker-compose.yml

---
version: "3"
services:
  db:
    restart: always
    image: postgres:16-alpine
    container_name: feast_db
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=feature_store
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=test

feature_store.yaml

project: project_name
provider: local
registry:
    registry_type: sql
    path: postgresql://postgres:[email protected]:5432/feature_store

Python script

from datetime import timedelta

import pandas as pd
from feast import (
    Entity,
    FeatureService,
    FeatureStore,
    FeatureView,
    Field,
    SnowflakeSource,
    ValueType,
)
from feast.types import Float32

feature_store = FeatureStore()

# Apply
entity = Entity(
    name="entity",
    join_keys=["ID"],
    value_type=ValueType.STRING,
)

source = SnowflakeSource(
    name="source_snowflake",
    timestamp_field="EVENT_TIMESTAMP",
    schema="TEMP",
    table="FEAST_FEATURES",
)

feature_view = FeatureView(
    name="feature_view__v1",
    entities=[entity],
    ttl=timedelta(days=0),
    schema=[
        Field(name="FEATURE", dtype=Float32),
    ],
    online=True,
    source=source,
)

feature_service = FeatureService(
    name="feature_service__v1",
    features=[feature_view],
)

feature_store.apply(
    [
        entity,
        source,
        feature_view,
        feature_service,
    ]
)

# Inference
entity_rows = [{"ID": "ID1"}, {"ID": "ID2"}]
entity_df = pd.DataFrame(entity_rows)
entity_df["event_timestamp"] = pd.to_datetime("now", utc=True)

online_features = feature_store.get_online_features(
    entity_rows=entity_rows,
    features=feature_service,
).to_dict()

print(online_features)

Specifications

Using postgres registry.

  • Version: 0.36.0
  • Platform: MacOS - M1
  • Subsystem: Sonoma 14.1.1

Possible Solution

I have little to no experience with proto, so I'm not sure whether it would be possible to load the None value directly from the proto definition.

One potential solution would be to check whether an empty string is loaded for this field when loading from proto, and then set it to None in the from_proto function.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions