Skip to content

Commit 327d99d

Browse files
authored
feat: Serialization version 2 deprecation notice (feast-dev#5248)
Serialization version 2 deprecation notice Signed-off-by: jyejare <[email protected]>
1 parent 0a09622 commit 327d99d

File tree

4 files changed

+107
-7
lines changed

4 files changed

+107
-7
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Entity Key Re-Serialization from Version 2 to 3
2+
3+
Entity Key Serialization version 2 will soon be deprecated, hence we need to shift the serialization and deserilization to version 3.
4+
5+
But here comes the challegnge where existing FeatuteViews on stores has written features with version 2. A version 2 serialized entity key cant be retrived using version 3 deserilization algorithm.
6+
7+
## Reserialize the Feature Views entity Keys to version 3
8+
9+
The solution is to reserialize the entity keys from version 2 to version 3.
10+
11+
Follow the following procedures to reserialize the entity key to version 3 in feature View in an offline / online store.
12+
13+
In hosrt, you need to iterate through all the feature views in your Feast repository, retrieve their serialized entity keys (if stored in version 2), reserialize them to version 3, and then update the online/offline store or wherever the serialized keys are stored.
14+
15+
### 1. Initialize the Feature Store
16+
17+
Load the FeatureStore object to access all feature views in your repository.
18+
19+
### 2. Iterate Through Feature Views
20+
21+
Use the list_feature_views() method to retrieve all feature views in the repository.
22+
23+
### 3. Retrieve Serialized Entity Keys
24+
25+
For each feature view, retrieve the serialized entity keys stored in the online/offline store or other storage
26+
27+
### 4. Reserialize Entity Keys
28+
29+
Use the reserialize_entity_v2_key_to_v3 function to convert the serialized keys from version 2 to version 3. Use [entity key encoding utils](https://github.com/feast-dev/feast/blob/master/sdk/python/feast/infra/key_encoding_utils.py) function `reserialize_entity_v2_key_to_v3`.
30+
31+
### 5. Update the Online/offline Store
32+
33+
Write the reserialized keys back to the online/offline store or the appropriate storage

sdk/python/feast/infra/key_encoding_utils.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,52 @@ def serialize_entity_key_prefix(entity_keys: List[str]) -> bytes:
5757
return b"".join(output)
5858

5959

60+
def reserialize_entity_v2_key_to_v3(
61+
serialized_key_v2: bytes,
62+
) -> bytes:
63+
"""
64+
Deserialize version 2 entity key and reserialize it to version 3.
65+
66+
Args:
67+
serialized_key_v2: serialized entity key of version 2
68+
69+
Returns: bytes of the serialized entity key in version 3
70+
"""
71+
offset = 0
72+
keys = []
73+
values = []
74+
num_keys = 1
75+
for _ in range(num_keys):
76+
value_type = struct.unpack_from("<I", serialized_key_v2, offset)[0]
77+
offset += 4
78+
print(f"Value Type: {value_type}")
79+
80+
fixed_tail_size = 4 + 4 + 8
81+
string_end = len(serialized_key_v2) - fixed_tail_size
82+
83+
key = serialized_key_v2[offset:string_end].decode("utf-8")
84+
keys.append(key)
85+
offset = string_end
86+
87+
while offset < len(serialized_key_v2):
88+
(value_type,) = struct.unpack_from("<I", serialized_key_v2, offset)
89+
offset += 4
90+
91+
(value_length,) = struct.unpack_from("<I", serialized_key_v2, offset)
92+
offset += 4
93+
94+
# Read the value based on its type and length
95+
value_bytes = serialized_key_v2[offset : offset + value_length]
96+
value = _deserialize_value(value_type, value_bytes)
97+
values.append(value)
98+
offset += value_length
99+
100+
return serialize_entity_key(
101+
EntityKeyProto(join_keys=keys, entity_values=values),
102+
entity_key_serialization_version=3,
103+
)
104+
105+
60106
def serialize_entity_key(
61107
entity_key: EntityKeyProto, entity_key_serialization_version=1
62108
) -> bytes:

sdk/python/feast/repo_config.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,11 @@ def __init__(self, **data: Any):
264264
self.feature_server["type"]
265265
)(**self.feature_server)
266266

267-
if self.entity_key_serialization_version <= 1:
267+
if self.entity_key_serialization_version <= 2:
268268
warnings.warn(
269-
"`entity_key_serialization_version` is either not specified in the feature_store.yaml, "
270-
"or is specified to a value <= 1."
271-
"This serialization version may cause errors when trying to write fields with the `Long` data type"
272-
" into the online store. Specifying `entity_key_serialization_version` to 2 is recommended for"
273-
" new projects. ",
274-
RuntimeWarning,
269+
"The serialization version 2 and below would be deprecated in the next release. "
270+
"Specifying `entity_key_serialization_version` to 3 is recommended.",
271+
DeprecationWarning,
275272
)
276273

277274
@property

sdk/python/tests/unit/infra/test_key_encoding_utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
_deserialize_value,
55
_serialize_val,
66
deserialize_entity_key,
7+
reserialize_entity_v2_key_to_v3,
78
serialize_entity_key,
89
)
910
from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto
@@ -115,3 +116,26 @@ def test_deserialize_value():
115116

116117
v = _deserialize_value(ValueType.INT64, b"\x01\x00\x00\x00\x00\x00\x00\x00")
117118
assert v.int64_val == 1
119+
120+
121+
def test_reserialize_entity_v2_key_to_v3():
122+
entity_key_proto_v2 = EntityKeyProto(
123+
join_keys=["user"],
124+
entity_values=[ValueProto(int64_val=int(2**15))],
125+
)
126+
serialized_key_v2 = serialize_entity_key(
127+
entity_key_proto_v2,
128+
entity_key_serialization_version=2,
129+
)
130+
131+
serialized_key_v3 = reserialize_entity_v2_key_to_v3(serialized_key_v2)
132+
133+
deserialized_key_v3 = deserialize_entity_key(
134+
serialized_key_v3,
135+
entity_key_serialization_version=3,
136+
)
137+
138+
assert deserialized_key_v3 == EntityKeyProto(
139+
join_keys=["user"],
140+
entity_values=[ValueProto(int64_val=int(2**15))],
141+
)

0 commit comments

Comments
 (0)