add rename key to sort key

This commit is contained in:
2025-08-19 15:04:37 -03:00
parent 3ee190c66f
commit 18221ee1f4
4 changed files with 71 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
import json import json
import logging import logging
import os import os
import warnings
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from base64 import urlsafe_b64decode, urlsafe_b64encode from base64 import urlsafe_b64decode, urlsafe_b64encode
from dataclasses import dataclass from dataclasses import dataclass
@@ -33,7 +34,7 @@ serializer = TypeSerializer()
deserializer = TypeDeserializer() deserializer = TypeDeserializer()
def _serialize_to_basic_types(data: Any) -> str | dict | set: def _serialize_to_basic_types(data: Any) -> str | dict | set | list:
match data: match data:
case datetime(): case datetime():
return data.isoformat() return data.isoformat()
@@ -42,7 +43,12 @@ def _serialize_to_basic_types(data: Any) -> str | dict | set:
case IPv4Address(): case IPv4Address():
return str(data) return str(data)
case tuple() | list(): case tuple() | list():
return set(_serialize_to_basic_types(v) for v in data) serialized = [_serialize_to_basic_types(v) for v in data]
if any(isinstance(v, dict) for v in serialized):
return serialized
return set(serialized)
case dict(): case dict():
return {k: _serialize_to_basic_types(v) for k, v in data.items()} return {k: _serialize_to_basic_types(v) for k, v in data.items()}
case _: case _:
@@ -85,6 +91,12 @@ else:
*, *,
delimiter: str = '#', delimiter: str = '#',
) -> str: ) -> str:
warnings.warn(
'ComposeKey() is deprecated and will be removed in the future.',
DeprecationWarning,
stacklevel=2,
)
if isinstance(keyparts, str): if isinstance(keyparts, str):
keyparts = (keyparts,) keyparts = (keyparts,)
@@ -119,6 +131,12 @@ else:
class PrefixKey(str): class PrefixKey(str):
def __new__(cls, prefix: str, delimiter: str | None = '#') -> str: def __new__(cls, prefix: str, delimiter: str | None = '#') -> str:
warnings.warn(
'PrefixKey() is deprecated and will be removed in the future.',
DeprecationWarning,
stacklevel=2,
)
if not delimiter: if not delimiter:
return super().__new__(cls, prefix) return super().__new__(cls, prefix)
@@ -145,12 +163,15 @@ if TYPE_CHECKING:
The sort key value. The sort key value.
path_spec: str, optional path_spec: str, optional
Optional specification for nested data extraction. Optional specification for nested data extraction.
rename_key : str, optional
If provided, renames the sort key in the output.
remove_prefix: str, optional remove_prefix: str, optional
Optional prefix to remove from the key when forming the result dict. Optional prefix to remove from the key when forming the result dict.
""" """
sk: str sk: str
path_spec: str | None = None path_spec: str | None = None
rename_key: str | None = None
remove_prefix: str | None = None remove_prefix: str | None = None
else: else:
@@ -166,6 +187,8 @@ else:
The sort key value. The sort key value.
path_spec: str, optional path_spec: str, optional
Optional specification for nested data extraction. Optional specification for nested data extraction.
rename_key : str, optional
If provided, renames the sort key in the output.
remove_prefix: str, optional remove_prefix: str, optional
Optional prefix to remove from the key when forming the result dict. Optional prefix to remove from the key when forming the result dict.
""" """
@@ -175,6 +198,7 @@ else:
sk: str, sk: str,
*, *,
path_spec: str | None = None, path_spec: str | None = None,
rename_key: str | None = None,
remove_prefix: str | None = None, remove_prefix: str | None = None,
) -> str: ) -> str:
return super().__new__(cls, sk) return super().__new__(cls, sk)
@@ -184,12 +208,14 @@ else:
sk: str, sk: str,
*, *,
path_spec: str | None = None, path_spec: str | None = None,
rename_key: str | None = None,
remove_prefix: str | None = None, remove_prefix: str | None = None,
) -> None: ) -> None:
# __init__ is used to store the parameters for later reference. # __init__ is used to store the parameters for later reference.
# For immutable types like str, __init__ cannot change the instance's value. # For immutable types like str, __init__ cannot change the instance's value.
self.sk = sk self.sk = sk
self.path_spec = path_spec self.path_spec = path_spec
self.rename_key = rename_key
self.remove_prefix = remove_prefix self.remove_prefix = remove_prefix
@@ -1074,6 +1100,9 @@ class DynamoDBCollection:
if pair.rename_key: if pair.rename_key:
return pair.rename_key return pair.rename_key
if getattr(sk, 'rename_key', None):
return sk.rename_key
if not isinstance(sk, SortKey): if not isinstance(sk, SortKey):
return pk return pk

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "layercake" name = "layercake"
version = "0.9.10" version = "0.9.12"
description = "Packages shared dependencies to optimize deployment and ensure consistency across functions." description = "Packages shared dependencies to optimize deployment and ensure consistency across functions."
readme = "README.md" readme = "README.md"
authors = [ authors = [

View File

@@ -31,24 +31,42 @@ def test_serialize():
'ip': {'S': '127.0.0.1'}, 'ip': {'S': '127.0.0.1'},
} }
assert serialize( assert (
'SS'
in serialize(
{'ids': ('1', '2', '3')}, {'ids': ('1', '2', '3')},
) == { )['ids']
'ids': { )
'L': [{'S': '1'}, {'S': '2'}, {'S': '3'}],
}
}
assert serialize( assert (
'SS'
in serialize(
{'ids': ['1', '2', '3']}, {'ids': ['1', '2', '3']},
) == { )['ids']
'ids': { )
'L': [{'S': '1'}, {'S': '2'}, {'S': '3'}],
}
}
assert serialize({'ids': {'1'}}) == {'ids': {'SS': ['1']}} assert serialize({'ids': {'1'}}) == {'ids': {'SS': ['1']}}
assert serialize(
{
'users': [
{'name': 'Sérgio'},
{'name': 'Tiago'},
]
},
) == {
'users': {
'L': [
{
'M': {'name': {'S': 'Sérgio'}},
},
{
'M': {'name': {'S': 'Tiago'}},
},
]
}
}
def test_composekey(): def test_composekey():
key = ComposeKey(('122', 'abc'), prefix='schedules', delimiter=':') key = ComposeKey(('122', 'abc'), prefix='schedules', delimiter=':')
@@ -263,7 +281,11 @@ def test_collection_get_items(
) )
+ SortKey('0') + SortKey('0')
+ SortKey('0') + SortKey('0')
+ SortKey('metadata#billing_policy', path_spec='payment_method') + SortKey(
'metadata#billing_policy',
path_spec='payment_method',
rename_key='payment_method',
)
+ SortKey('metadata#payment_policy', remove_prefix='metadata#'), + SortKey('metadata#payment_policy', remove_prefix='metadata#'),
) )
@@ -273,7 +295,7 @@ def test_collection_get_items(
'id': 'cJtK9SsnJhKPyxESe7g3DG', 'id': 'cJtK9SsnJhKPyxESe7g3DG',
'cnpj': '15608435000190', 'cnpj': '15608435000190',
'email': 'org+15608435000190@users.noreply.betaeducacao.com.br', 'email': 'org+15608435000190@users.noreply.betaeducacao.com.br',
'metadata#billing_policy': 'PIX', 'payment_method': 'PIX',
'payment_policy': {'due_days': Decimal('90')}, 'payment_policy': {'due_days': Decimal('90')},
} }

2
layercake/uv.lock generated
View File

@@ -675,7 +675,7 @@ wheels = [
[[package]] [[package]]
name = "layercake" name = "layercake"
version = "0.9.9" version = "0.9.11"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "arnparse" }, { name = "arnparse" },