remove prefix for partition key
This commit is contained in:
@@ -17,6 +17,7 @@ from layercake.dynamodb import (
|
|||||||
KeyPair,
|
KeyPair,
|
||||||
MissingError,
|
MissingError,
|
||||||
PartitionKey,
|
PartitionKey,
|
||||||
|
PrefixKey,
|
||||||
)
|
)
|
||||||
from pydantic import UUID4, BaseModel, StringConstraints
|
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)
|
start_key = router.current_event.get_query_string_value('start_key', None)
|
||||||
|
|
||||||
return collect.get_items(
|
return collect.get_items(
|
||||||
key=KeyPair(id, 'emails'),
|
KeyPair(id, PrefixKey('emails#')),
|
||||||
start_key=start_key,
|
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)
|
start_key = router.current_event.get_query_string_value('start_key', None)
|
||||||
|
|
||||||
return collect.get_items(
|
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,
|
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)
|
start_key = router.current_event.get_query_string_value('start_key', None)
|
||||||
|
|
||||||
return collect.get_items(
|
return collect.get_items(
|
||||||
key=KeyPair(id, 'orgs'),
|
KeyPair(id, PrefixKey('orgs#')),
|
||||||
start_key=start_key,
|
start_key=start_key,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def test_get_emails(
|
|||||||
{
|
{
|
||||||
'email_verified': True,
|
'email_verified': True,
|
||||||
'mx_record_exists': True,
|
'mx_record_exists': True,
|
||||||
'sk': 'emails#sergio@somosbeta.com.br',
|
'sk': 'sergio@somosbeta.com.br',
|
||||||
'email_primary': True,
|
'email_primary': True,
|
||||||
'id': '5OxmMjL-ujoR5IMGegQz',
|
'id': '5OxmMjL-ujoR5IMGegQz',
|
||||||
'create_date': '2019-03-25T00:00:00-03:00',
|
'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(
|
def test_post_user(
|
||||||
mock_app,
|
mock_app,
|
||||||
http_api_proxy: HttpApiProxy,
|
http_api_proxy: HttpApiProxy,
|
||||||
|
|||||||
@@ -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#*"}, "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": "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": "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": "log: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": "2019-03-25T00:00:00-03:00"}, "action": {"S": "CLICK_EMAIL"}}
|
||||||
|
|||||||
@@ -669,10 +669,12 @@ class DynamoDBCollection:
|
|||||||
items = res['items']
|
items = res['items']
|
||||||
last_key = _startkey_b64encode(res['last_key']) if res['last_key'] else None
|
last_key = _startkey_b64encode(res['last_key']) if res['last_key'] else None
|
||||||
|
|
||||||
# Remove prefix from Sort Key if `key[SK]` is a PrefixKey
|
match key.get(PK), key.get(SK):
|
||||||
if isinstance(key.get(SK), PrefixKey):
|
case ComposeKey(), _: # Remove prefix from Partition Key
|
||||||
prefix = key[SK].prefix
|
prefix = key[PK].prefix + key[PK].delimiter
|
||||||
items = [item | {SK: item[SK].removeprefix(prefix)} for item in items]
|
items = _remove_prefix(items, PK, prefix)
|
||||||
|
case _, PrefixKey(): # Remove prefix from Sort Key
|
||||||
|
items = _remove_prefix(items, SK, key[SK].prefix)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'items': items,
|
'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:
|
def _startkey_b64encode(obj: dict) -> str:
|
||||||
s = json.dumps(obj)
|
s = json.dumps(obj)
|
||||||
b = urlsafe_b64encode(s.encode('utf-8')).decode('utf-8')
|
b = urlsafe_b64encode(s.encode('utf-8')).decode('utf-8')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "layercake"
|
name = "layercake"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
description = "Add your description here"
|
description = "Add your description here"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
@@ -171,18 +171,33 @@ def test_collection_get_items(
|
|||||||
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
||||||
|
|
||||||
# This data was added from seeds
|
# This data was added from seeds
|
||||||
data = collect.get_items(
|
logs = collect.get_items(
|
||||||
PartitionKey(
|
PartitionKey(
|
||||||
ComposeKey('5OxmMjL-ujoR5IMGegQz', prefix='logs'),
|
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
|
# This data was added from seeds
|
||||||
data = collect.get_items(
|
emails = collect.get_items(
|
||||||
KeyPair('5OxmMjL-ujoR5IMGegQz', PrefixKey('emails#')),
|
KeyPair('5OxmMjL-ujoR5IMGegQz', PrefixKey('emails#')),
|
||||||
)
|
)
|
||||||
assert data == {
|
assert emails == {
|
||||||
'items': [
|
'items': [
|
||||||
{
|
{
|
||||||
'email_verified': True,
|
'email_verified': True,
|
||||||
|
|||||||
2
layercake/uv.lock
generated
2
layercake/uv.lock
generated
@@ -417,7 +417,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "layercake"
|
name = "layercake"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aws-lambda-powertools", extra = ["all"] },
|
{ name = "aws-lambda-powertools", extra = ["all"] },
|
||||||
|
|||||||
Reference in New Issue
Block a user