-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: Schema update #2509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Schema update #2509
Changes from 1 commit
1802ac4
5fd414d
9f677c7
2122172
53f3439
d404a4a
f7005d7
a7a7703
156b171
512e00f
8d62f0c
eb6bf3c
fba1388
a25a3b5
7d073d5
6fcdaff
f91d9bd
a71eaf9
a8880cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Signed-off-by: Kevin Zhang <kzhang@tecton.ai>
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,9 +13,10 @@ | |
| # limitations under the License. | ||
|
|
||
| import enum | ||
| import re | ||
| import warnings | ||
| from abc import ABC, abstractmethod | ||
| from typing import Any, Callable, Dict, Iterable, Optional, Tuple | ||
| from typing import Any, Callable, Dict, Iterable, Optional, Tuple, Union, List | ||
|
|
||
| from google.protobuf.json_format import MessageToJson | ||
|
|
||
|
|
@@ -24,6 +25,9 @@ | |
| from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto | ||
| from feast.repo_config import RepoConfig, get_data_source_class_from_type | ||
| from feast.value_type import ValueType | ||
| from numpy import deprecate | ||
| from feast.field import Field | ||
| from feast.types import VALUE_TYPES_TO_FEAST_TYPES | ||
|
|
||
|
|
||
| class SourceType(enum.Enum): | ||
|
|
@@ -449,26 +453,32 @@ class RequestSource(DataSource): | |
|
|
||
| Args: | ||
| name: Name of the request data source | ||
| schema: Schema mapping from the input feature name to a ValueType | ||
| schema Union[Dict[str, ValueType], List[Field]]: Schema mapping from the input feature name to a ValueType | ||
| description (optional): A human-readable description. | ||
| tags (optional): A dictionary of key-value pairs to store arbitrary metadata. | ||
| owner (optional): The owner of the request data source, typically the email of the primary | ||
| maintainer. | ||
| """ | ||
|
|
||
| name: str | ||
| schema: Dict[str, ValueType] | ||
| schema: Union[Dict[str, ValueType], List[Field]] | ||
|
|
||
| def __init__( | ||
| self, | ||
| name: str, | ||
| schema: Dict[str, ValueType], | ||
| schema: Union[Dict[str, ValueType], List[Field]], | ||
| description: Optional[str] = "", | ||
| tags: Optional[Dict[str, str]] = None, | ||
| owner: Optional[str] = "", | ||
| ): | ||
| """Creates a RequestSource object.""" | ||
| super().__init__(name=name, description=description, tags=tags, owner=owner) | ||
| if isinstance(schema, Dict): | ||
| warnings.warn( | ||
| "Schema in RequestSource is changing type. The schema data type Dict[str, ValueType] is being deprecated in Feast 0.23. " | ||
| "Please use List[Field] instead for the schema", | ||
| DeprecationWarning, | ||
| ) | ||
| self.schema = schema | ||
|
|
||
| def validate(self, config: RepoConfig): | ||
|
|
@@ -479,12 +489,67 @@ def get_table_column_names_and_types( | |
| ) -> Iterable[Tuple[str, str]]: | ||
| pass | ||
|
|
||
| def __eq__(self, other): | ||
| if not isinstance(other, RequestSource): | ||
| raise TypeError( | ||
| "Comparisons should only involve RequestSource class objects." | ||
| ) | ||
| if ( | ||
| self.name != other.name or | ||
| self.description != other.description or | ||
| self.owner != other.owner or | ||
| self.tags != other.tags | ||
| ): | ||
| return False | ||
| else: | ||
| if isinstance(self.schema, List) and isinstance(other.schema, List): | ||
| for field1, field2 in zip(self.schema, other.schema): | ||
| if field1 != field2: | ||
| return False | ||
| return True | ||
| elif isinstance(self.schema, Dict) and isinstance(other.schema, Dict): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should check here that
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated, by just setting schema to list instead. |
||
| for key, value in self.schema.items(): | ||
| if key not in other.schema: | ||
| return False | ||
| elif value != other.schema[key]: | ||
| return False | ||
| return True | ||
| elif isinstance(self.schema, Dict) and isinstance(other.schema, List): | ||
| dict_schema = self.schema | ||
| list_schema = other.schema | ||
| elif isinstance(self.schema, List) and isinstance(other.schema, Dict): | ||
| dict_schema = other.schema | ||
| list_schema = self.schema | ||
|
|
||
| temp_schema = {} | ||
| for field in list_schema: | ||
| temp_schema[field.name] = field.dtype | ||
| for name, value in dict_schema.items(): | ||
| if name not in temp_schema: | ||
| return False | ||
| elif VALUE_TYPES_TO_FEAST_TYPES[value.value] != temp_schema[name]: | ||
| return False | ||
| return True | ||
|
|
||
| @staticmethod | ||
| def from_proto(data_source: DataSourceProto): | ||
|
|
||
| deprecated_schema = data_source.request_data_options.deprecated_schema | ||
| schema_pb = data_source.request_data_options.schema | ||
| schema = {} | ||
| for key, val in schema_pb.items(): | ||
| schema[key] = ValueType(val) | ||
|
|
||
| schema = [] | ||
| if deprecated_schema and not schema_pb: | ||
| warnings.warn( | ||
| "Schema in RequestSource is changing type. The schema data type Dict[str, ValueType] is being deprecated in Feast 0.23. " | ||
| "Please use List[Field] instead for the schema", | ||
| DeprecationWarning, | ||
| ) | ||
| for key, val in deprecated_schema.items(): | ||
| schema[key] = ValueType(val) | ||
| else: | ||
| for field_proto in schema_pb: | ||
| schema.append(Field.from_proto(field_proto)) | ||
|
|
||
| return RequestSource( | ||
| name=data_source.name, | ||
| schema=schema, | ||
|
|
@@ -494,18 +559,23 @@ def from_proto(data_source: DataSourceProto): | |
| ) | ||
|
|
||
| def to_proto(self) -> DataSourceProto: | ||
| schema_pb = {} | ||
| for key, value in self.schema.items(): | ||
| schema_pb[key] = value.value | ||
| options = DataSourceProto.RequestDataOptions(schema=schema_pb) | ||
|
|
||
| schema_pb = [] | ||
|
|
||
| if isinstance(self.schema, Dict): | ||
| for key, value in self.schema.items(): | ||
| schema_pb.append(Field(name=key, dtype=VALUE_TYPES_TO_FEAST_TYPES[value.value]).to_proto()) | ||
| else: | ||
| for field in self.schema: | ||
| schema_pb.append(field.to_proto()) | ||
| data_source_proto = DataSourceProto( | ||
| name=self.name, | ||
| type=DataSourceProto.REQUEST_SOURCE, | ||
| request_data_options=options, | ||
| description=self.description, | ||
| tags=self.tags, | ||
| owner=self.owner, | ||
| ) | ||
| data_source_proto.request_data_options.schema.extend(schema_pb) | ||
|
|
||
| return data_source_proto | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,9 @@ | |
| ValueType, | ||
| ) | ||
| from feast.data_source import DataSource, RequestSource | ||
| from feast.types import FeastType | ||
| from feast.types import FeastType, PrimitiveFeastType | ||
| from tests.integration.feature_repos.universal.entities import location | ||
|
|
||
| from feast.field import Field | ||
|
|
||
| def driver_feature_view( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this not being used anywhere?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think my rebase must have accidentally deleted it, i added it back. |
||
| data_source: DataSource, | ||
|
|
@@ -123,7 +123,11 @@ def similarity_feature_view( | |
|
|
||
|
|
||
| def create_conv_rate_request_source(): | ||
| return RequestSource(name="conv_rate_input", schema={"val_to_add": ValueType.INT32}) | ||
| return RequestSource( | ||
| name="conv_rate_input", | ||
| schema=[ | ||
| Field(name="val_to_add", dtype=PrimitiveFeastType.INT32), | ||
| ]) | ||
|
|
||
|
|
||
| def create_similarity_request_source(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the internals should always be using
List[Field], and we convert to that in__init__andfrom_proto? Or is this field exposed to users directly, and it would break them if we changed it's type?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually looking at the
from_protomethod we're changing the type of this field anywayThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, removing union.