GeezerVison is showing github.com — feat: Support for Map value data type (#5768) (#5772) · feast-dev/feast@373b892
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: docs/reference/type-system.md +1Lines changed: 1 addition & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| 4 | 4 |
| 5 | 5 | Feast uses an internal type system to provide guarantees on training and serving data. | 6 | 6 | Feast currently supports eight primitive types - `INT32`, `INT64`, `FLOAT32`, `FLOAT64`, `STRING`, `BYTES`, `BOOL`, and `UNIX_TIMESTAMP` - and the corresponding array types. | | 7 | +Map type is also supported using a key of `STRING` type and any supported feast type as a value. | 7 | 8 | Null types are not supported, although the `UNIX_TIMESTAMP` type is nullable. | 8 | 9 | The type system is controlled by [`Value.proto`](https://github.com/feast-dev/feast/blob/master/protos/feast/types/Value.proto) in protobuf and by [`types.py`](https://github.com/feast-dev/feast/blob/master/sdk/python/feast/types.py) in Python. | 9 | 10 | Type conversion logic can be found in [`type_map.py`](https://github.com/feast-dev/feast/blob/master/sdk/python/feast/type_map.py). | |
Collapse file Copy file name to clipboardExpand all lines: protos/feast/types/Value.proto +14-1Lines changed: 14 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | + | 1 | 2 | /* | 2 | 3 | * Copyright 2018 The Feast Authors | 3 | 4 | * | @@ -42,6 +43,8 @@ message ValueType { | 42 | 43 | BOOL_LIST = 17; | 43 | 44 | UNIX_TIMESTAMP_LIST = 18; | 44 | 45 | NULL = 19; | | 46 | + MAP = 20; | | 47 | + MAP_LIST = 21; | 45 | 48 | } | 46 | 49 | } | 47 | 50 |
| @@ -67,6 +70,8 @@ message Value { | 67 | 70 | BoolList bool_list_val = 17; | 68 | 71 | Int64List unix_timestamp_list_val = 18; | 69 | 72 | Null null_val = 19; | | 73 | + Map map_val = 20; | | 74 | + MapList map_list_val = 21; | 70 | 75 | } | 71 | 76 | } | 72 | 77 |
| @@ -102,8 +107,16 @@ message BoolList { | 102 | 107 | repeated bool val = 1; | 103 | 108 | } | 104 | 109 |
| | 110 | +message Map { | | 111 | + map<string, Value> val = 1; | | 112 | +} | | 113 | + | | 114 | +message MapList { | | 115 | + repeated Map val = 1; | | 116 | +} | | 117 | + | 105 | 118 | // This is to avoid an issue of being unable to specify `repeated value` in oneofs or maps | 106 | 119 | // In JSON "val" field can be omitted | 107 | 120 | message RepeatedValue { | 108 | 121 | repeated Value val = 1; | 109 | | -} | | 122 | +} |
Collapse file Copy file name to clipboardExpand all lines: sdk/python/feast/protos/feast/types/Value_pb2.py +31-23Lines changed: 31 additions & 23 deletions Collapse file Copy file name to clipboardExpand all lines: sdk/python/feast/protos/feast/types/Value_pb2.pyi +62-3Lines changed: 62 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -72,6 +72,8 @@ class ValueType(google.protobuf.message.Message): | 72 | 72 | BOOL_LIST: ValueType._Enum.ValueType # 17 | 73 | 73 | UNIX_TIMESTAMP_LIST: ValueType._Enum.ValueType # 18 | 74 | 74 | NULL: ValueType._Enum.ValueType # 19 | | 75 | + MAP: ValueType._Enum.ValueType # 20 | | 76 | + MAP_LIST: ValueType._Enum.ValueType # 21 | 75 | 77 |
| 76 | 78 | class Enum(_Enum, metaclass=_EnumEnumTypeWrapper): ... | 77 | 79 | INVALID: ValueType.Enum.ValueType # 0 | @@ -92,6 +94,8 @@ class ValueType(google.protobuf.message.Message): | 92 | 94 | BOOL_LIST: ValueType.Enum.ValueType # 17 | 93 | 95 | UNIX_TIMESTAMP_LIST: ValueType.Enum.ValueType # 18 | 94 | 96 | NULL: ValueType.Enum.ValueType # 19 | | 97 | + MAP: ValueType.Enum.ValueType # 20 | | 98 | + MAP_LIST: ValueType.Enum.ValueType # 21 | 95 | 99 |
| 96 | 100 | def __init__( | 97 | 101 | self, | @@ -119,6 +123,8 @@ class Value(google.protobuf.message.Message): | 119 | 123 | BOOL_LIST_VAL_FIELD_NUMBER: builtins.int | 120 | 124 | UNIX_TIMESTAMP_LIST_VAL_FIELD_NUMBER: builtins.int | 121 | 125 | NULL_VAL_FIELD_NUMBER: builtins.int | | 126 | + MAP_VAL_FIELD_NUMBER: builtins.int | | 127 | + MAP_LIST_VAL_FIELD_NUMBER: builtins.int | 122 | 128 | bytes_val: builtins.bytes | 123 | 129 | string_val: builtins.str | 124 | 130 | int32_val: builtins.int | @@ -144,6 +150,10 @@ class Value(google.protobuf.message.Message): | 144 | 150 | @property | 145 | 151 | def unix_timestamp_list_val(self) -> global___Int64List: ... | 146 | 152 | null_val: global___Null.ValueType | | 153 | + @property | | 154 | + def map_val(self) -> global___Map: ... | | 155 | + @property | | 156 | + def map_list_val(self) -> global___MapList: ... | 147 | 157 | def __init__( | 148 | 158 | self, | 149 | 159 | *, | @@ -164,10 +174,12 @@ class Value(google.protobuf.message.Message): | 164 | 174 | bool_list_val: global___BoolList | None = ..., | 165 | 175 | unix_timestamp_list_val: global___Int64List | None = ..., | 166 | 176 | null_val: global___Null.ValueType = ..., | | 177 | + map_val: global___Map | None = ..., | | 178 | + map_list_val: global___MapList | None = ..., | 167 | 179 | ) -> None: ... | 168 | | - def HasField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_val", b"int64_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_val", b"string_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> builtins.bool: ... | 169 | | - def ClearField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_val", b"int64_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_val", b"string_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> None: ... | 170 | | - def WhichOneof(self, oneof_group: typing_extensions.Literal["val", b"val"]) -> typing_extensions.Literal["bytes_val", "string_val", "int32_val", "int64_val", "double_val", "float_val", "bool_val", "unix_timestamp_val", "bytes_list_val", "string_list_val", "int32_list_val", "int64_list_val", "double_list_val", "float_list_val", "bool_list_val", "unix_timestamp_list_val", "null_val"] | None: ... | | 180 | + def HasField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_val", b"int64_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_val", b"string_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> builtins.bool: ... | | 181 | + def ClearField(self, field_name: typing_extensions.Literal["bool_list_val", b"bool_list_val", "bool_val", b"bool_val", "bytes_list_val", b"bytes_list_val", "bytes_val", b"bytes_val", "double_list_val", b"double_list_val", "double_val", b"double_val", "float_list_val", b"float_list_val", "float_val", b"float_val", "int32_list_val", b"int32_list_val", "int32_val", b"int32_val", "int64_list_val", b"int64_list_val", "int64_val", b"int64_val", "map_list_val", b"map_list_val", "map_val", b"map_val", "null_val", b"null_val", "string_list_val", b"string_list_val", "string_val", b"string_val", "unix_timestamp_list_val", b"unix_timestamp_list_val", "unix_timestamp_val", b"unix_timestamp_val", "val", b"val"]) -> None: ... | | 182 | + def WhichOneof(self, oneof_group: typing_extensions.Literal["val", b"val"]) -> typing_extensions.Literal["bytes_val", "string_val", "int32_val", "int64_val", "double_val", "float_val", "bool_val", "unix_timestamp_val", "bytes_list_val", "string_list_val", "int32_list_val", "int64_list_val", "double_list_val", "float_list_val", "bool_list_val", "unix_timestamp_list_val", "null_val", "map_val", "map_list_val"] | None: ... | 171 | 183 |
| 172 | 184 | global___Value = Value | 173 | 185 |
| @@ -276,6 +288,53 @@ class BoolList(google.protobuf.message.Message): | 276 | 288 |
| 277 | 289 | global___BoolList = BoolList | 278 | 290 |
| | 291 | +class Map(google.protobuf.message.Message): | | 292 | + DESCRIPTOR: google.protobuf.descriptor.Descriptor | | 293 | + | | 294 | + class ValEntry(google.protobuf.message.Message): | | 295 | + DESCRIPTOR: google.protobuf.descriptor.Descriptor | | 296 | + | | 297 | + KEY_FIELD_NUMBER: builtins.int | | 298 | + VALUE_FIELD_NUMBER: builtins.int | | 299 | + key: builtins.str | | 300 | + @property | | 301 | + def value(self) -> global___Value: ... | | 302 | + def __init__( | | 303 | + self, | | 304 | + *, | | 305 | + key: builtins.str = ..., | | 306 | + value: global___Value | None = ..., | | 307 | + ) -> None: ... | | 308 | + def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... | | 309 | + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... | | 310 | + | | 311 | + VAL_FIELD_NUMBER: builtins.int | | 312 | + @property | | 313 | + def val(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Value]: ... | | 314 | + def __init__( | | 315 | + self, | | 316 | + *, | | 317 | + val: collections.abc.Mapping[builtins.str, global___Value] | None = ..., | | 318 | + ) -> None: ... | | 319 | + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... | | 320 | + | | 321 | +global___Map = Map | | 322 | + | | 323 | +class MapList(google.protobuf.message.Message): | | 324 | + DESCRIPTOR: google.protobuf.descriptor.Descriptor | | 325 | + | | 326 | + VAL_FIELD_NUMBER: builtins.int | | 327 | + @property | | 328 | + def val(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Map]: ... | | 329 | + def __init__( | | 330 | + self, | | 331 | + *, | | 332 | + val: collections.abc.Iterable[global___Map] | None = ..., | | 333 | + ) -> None: ... | | 334 | + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... | | 335 | + | | 336 | +global___MapList = MapList | | 337 | + | 279 | 338 | class RepeatedValue(google.protobuf.message.Message): | 280 | 339 | """This is to avoid an issue of being unable to specify `repeated value` in oneofs or maps | 281 | 340 | In JSON "val" field can be omitted | |
|