remove prefix for partition key

This commit is contained in:
2025-03-26 15:27:26 -03:00
parent 3564119581
commit 3d6801df70
7 changed files with 68 additions and 16 deletions

View File

@@ -17,6 +17,7 @@ from layercake.dynamodb import (
KeyPair,
MissingError,
PartitionKey,
PrefixKey,
)
from pydantic import UUID4, BaseModel, StringConstraints
@@ -89,7 +90,7 @@ def get_emails(id: str):
start_key = router.current_event.get_query_string_value('start_key', None)
return collect.get_items(
key=KeyPair(id, 'emails'),
KeyPair(id, PrefixKey('emails#')),
start_key=start_key,
)
@@ -104,7 +105,9 @@ def get_logs(id: str):
start_key = router.current_event.get_query_string_value('start_key', None)
return collect.get_items(
key=PartitionKey(ComposeKey(id, prefix='log', delimiter=':')),
# Post-migration: uncomment to enable PartitionKey with a composite key (id with `logs` prefix).
# PartitionKey(ComposeKey(id, prefix='logs')),
PartitionKey(ComposeKey(id, prefix='log', delimiter=':')),
start_key=start_key,
)
@@ -119,6 +122,6 @@ def get_orgs(id: str):
start_key = router.current_event.get_query_string_value('start_key', None)
return collect.get_items(
key=KeyPair(id, 'orgs'),
KeyPair(id, PrefixKey('orgs#')),
start_key=start_key,
)

View File

@@ -29,7 +29,7 @@ def test_get_emails(
{
'email_verified': True,
'mx_record_exists': True,
'sk': 'emails#sergio@somosbeta.com.br',
'sk': 'sergio@somosbeta.com.br',
'email_primary': True,
'id': '5OxmMjL-ujoR5IMGegQz',
'create_date': '2019-03-25T00:00:00-03:00',
@@ -40,6 +40,28 @@ def test_get_emails(
}
def test_get_logs(
mock_app,
dynamodb_seeds,
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
http_api_proxy: HttpApiProxy,
lambda_context: LambdaContext,
):
mock_app.users.collect = DynamoDBCollection(dynamodb_persistence_layer)
r = mock_app.lambda_handler(
http_api_proxy(
raw_path='/users/5OxmMjL-ujoR5IMGegQz/logs',
method=HTTPMethod.GET,
),
lambda_context,
)
assert r['statusCode'] == HTTPStatus.OK
print(r['body'])
def test_post_user(
mock_app,
http_api_proxy: HttpApiProxy,

View File

@@ -4,5 +4,5 @@
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "acls#*"}, "create_date": {"S": "2022-06-13T15:00:24.309410-03:00"}, "roles": {"L": [{"S": "ADMIN"}]}}
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "acls#cJtK9SsnJhKPyxESe7g3DG"}, "create_date": {"S": "2025-03-14T10:06:34.628078-03:00"}, "roles": {"L": [{"S": "ADMIN"}]}}
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "orgs#cJtK9SsnJhKPyxESe7g3DG"}, "cnpj": {"S": "15608435000190"}, "create_date": {"S": "2025-03-13T16:36:50.073156-03:00"}, "name": {"S": "Beta Educação"}}
{"id": {"S": "logs#5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2024-02-08T16:42:33.776409-03:00"}, "action": {"S": "OPEN_EMAIL"}}
{"id": {"S": "logs#5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2019-03-25T00:00:00-03:00"}, "action": {"S": "CLICK_EMAIL"}}
{"id": {"S": "log:5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2024-02-08T16:42:33.776409-03:00"}, "action": {"S": "OPEN_EMAIL"}}
{"id": {"S": "log:5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "2019-03-25T00:00:00-03:00"}, "action": {"S": "CLICK_EMAIL"}}

View File

@@ -669,10 +669,12 @@ class DynamoDBCollection:
items = res['items']
last_key = _startkey_b64encode(res['last_key']) if res['last_key'] else None
# Remove prefix from Sort Key if `key[SK]` is a PrefixKey
if isinstance(key.get(SK), PrefixKey):
prefix = key[SK].prefix
items = [item | {SK: item[SK].removeprefix(prefix)} for item in items]
match key.get(PK), key.get(SK):
case ComposeKey(), _: # Remove prefix from Partition Key
prefix = key[PK].prefix + key[PK].delimiter
items = _remove_prefix(items, PK, prefix)
case _, PrefixKey(): # Remove prefix from Sort Key
items = _remove_prefix(items, SK, key[SK].prefix)
return {
'items': items,
@@ -680,6 +682,16 @@ class DynamoDBCollection:
}
def _remove_prefix(
items: list[dict[str, Any]],
/,
key: str,
prefix: str,
) -> list[dict[str, Any]]:
"""Remove the given prefix from the value associated with key in each item."""
return [x | {key: x[key].removeprefix(prefix)} for x in items]
def _startkey_b64encode(obj: dict) -> str:
s = json.dumps(obj)
b = urlsafe_b64encode(s.encode('utf-8')).decode('utf-8')

View File

@@ -1,6 +1,6 @@
[project]
name = "layercake"
version = "0.1.1"
version = "0.1.2"
description = "Add your description here"
readme = "README.md"
authors = [

View File

@@ -171,18 +171,33 @@ def test_collection_get_items(
collect = DynamoDBCollection(dynamodb_persistence_layer)
# This data was added from seeds
data = collect.get_items(
logs = collect.get_items(
PartitionKey(
ComposeKey('5OxmMjL-ujoR5IMGegQz', prefix='logs'),
),
)
assert len(data['items']) == 2
assert len(logs['items']) == 2
assert logs == {
'items': [
{
'sk': '2024-02-08T16:42:33.776409-03:00',
'action': 'OPEN_EMAIL',
'id': '5OxmMjL-ujoR5IMGegQz',
},
{
'sk': '2019-03-25T00:00:00-03:00',
'action': 'CLICK_EMAIL',
'id': '5OxmMjL-ujoR5IMGegQz',
},
],
'last_key': None,
}
# This data was added from seeds
data = collect.get_items(
emails = collect.get_items(
KeyPair('5OxmMjL-ujoR5IMGegQz', PrefixKey('emails#')),
)
assert data == {
assert emails == {
'items': [
{
'email_verified': True,

2
layercake/uv.lock generated
View File

@@ -417,7 +417,7 @@ wheels = [
[[package]]
name = "layercake"
version = "0.1.0"
version = "0.1.1"
source = { editable = "." }
dependencies = [
{ name = "aws-lambda-powertools", extra = ["all"] },