boto3-assist 0.1.5__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/PKG-INFO +1 -1
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/pyproject.toml +1 -1
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/connection_tracker.py +25 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_model_base.py +27 -2
- boto3_assist-0.1.6/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +45 -0
- boto3_assist-0.1.6/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +574 -0
- boto3_assist-0.1.6/src/boto3_assist/version.py +1 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/dynamodb/dynamodb_model_base_test.py +3 -78
- boto3_assist-0.1.6/tests/dynamodb/dynamodb_model_projections_test.py +56 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/dynamodb/dynamodb_reindex_test.py +1 -1
- boto3_assist-0.1.6/tests/dynamodb/models/user_model.py +89 -0
- boto3_assist-0.1.5/src/boto3_assist/version.py +0 -1
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.env.development +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.env.docker +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.env.docker.001 +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.env.docker.nosql.workbench +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.gitignore +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.vscode/launch.json +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.vscode/settings.json +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/.vscode/tasks.json +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/LICENSE.txt +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/README.md +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/aws_regions_with_status.csv +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/aws_regions_with_status.json +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/devops/build.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/devops/readme.md +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/models/order_item_model.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/models/order_model.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/models/product_model.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/models/user_model.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/models/user_post_model.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/order_example/main.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/order_example/products.json +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/order_item_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/order_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/product_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/table_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/user_post_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/user_service.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/user_service_client_example.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/user_service_resource_example.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/user_post_example/main.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/ec2/regions_report.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/module-headers.txt +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/mypy.ini +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/requirements-dev.txt +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/requirements.txt +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/run-checks.sh +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/boto3session.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_connection.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_connection_tracker.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_helpers.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/readme.md +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/ec2/ec2_connection.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/environment_services/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/environment_services/environment_loader.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/environment_services/environment_variables.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/utilities/datetime_utility.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/utilities/logging_utility.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/utilities/serialization_utility.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/utilities/string_utility.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/__top/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/dynamodb/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/examples_test/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/examples_test/user_service_test.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/utilities/__init__.py +0 -0
- {boto3_assist-0.1.5 → boto3_assist-0.1.6}/tests/utilities/serialization_utility_test.py +0 -0
|
@@ -4,6 +4,9 @@ Maintainers: Eric Wilson
|
|
|
4
4
|
MIT License. See Project Root for the license information.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import traceback
|
|
8
|
+
import os
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
class ConnectionTracker:
|
|
9
12
|
"""
|
|
@@ -12,23 +15,45 @@ class ConnectionTracker:
|
|
|
12
15
|
"""
|
|
13
16
|
|
|
14
17
|
def __init__(self, service_name: str) -> None:
|
|
18
|
+
self.__stack_trace_env_var: str = "ISSUE_STACK_TRACE"
|
|
15
19
|
self.__connection_couter: int = 0
|
|
16
20
|
self.__service_name: str = service_name
|
|
21
|
+
self.__issue_stack_trace: bool = (
|
|
22
|
+
os.getenv(f"{self.__stack_trace_env_var}", "false") == "true"
|
|
23
|
+
)
|
|
17
24
|
|
|
18
25
|
def increment_connection(self) -> None:
|
|
19
26
|
"""Increments the connection counter"""
|
|
20
27
|
self.__connection_couter += 1
|
|
21
28
|
|
|
22
29
|
if self.connection_count > 1:
|
|
30
|
+
service_message = ""
|
|
31
|
+
stack_trace_message = ""
|
|
32
|
+
if self.__service_name:
|
|
33
|
+
service_message = f"Your {self.__service_name} service has more than one connection.\n"
|
|
34
|
+
|
|
35
|
+
if not self.__issue_stack_trace:
|
|
36
|
+
stack_trace_message = (
|
|
37
|
+
f"\nTo add addtional information to the log and determine where additional connections are being created"
|
|
38
|
+
f", set the environment variable {self.__stack_trace_env_var} to true.\n"
|
|
39
|
+
)
|
|
23
40
|
self.__log_warning(
|
|
41
|
+
f"{service_message}"
|
|
24
42
|
f"Your dynamodb connection count is {self.connection_count}. "
|
|
25
43
|
"Under most circumstances you should be able to use the same connection "
|
|
26
44
|
"vs. creating a new one. Connections are expensive in terms of time / latency. "
|
|
27
45
|
"If you are seeing perforance issues, check how and where you are creating your "
|
|
28
46
|
"connections. You should be able to pass the .db connection to your other objects "
|
|
29
47
|
"and reuse your dynamodb boto connections."
|
|
48
|
+
f"{stack_trace_message}"
|
|
30
49
|
)
|
|
31
50
|
|
|
51
|
+
# do a stack trace
|
|
52
|
+
if self.__issue_stack_trace:
|
|
53
|
+
print("Stack Trace")
|
|
54
|
+
traceback.print_stack()
|
|
55
|
+
print("")
|
|
56
|
+
|
|
32
57
|
def decrement_connection(self) -> None:
|
|
33
58
|
"""Decrements the connection counter"""
|
|
34
59
|
self.__connection_couter -= 1
|
|
@@ -18,6 +18,7 @@ from boto3_assist.dynamodb.dynamodb_index import (
|
|
|
18
18
|
DynamoDBIndexes,
|
|
19
19
|
DynamoDBIndex,
|
|
20
20
|
)
|
|
21
|
+
from boto3_assist.dynamodb.dynamodb_reserved_words import DynamoDBReservedWords
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def exclude_from_serialization(method):
|
|
@@ -41,11 +42,13 @@ class DynamoDBModelBase:
|
|
|
41
42
|
|
|
42
43
|
T = TypeVar("T", bound="DynamoDBModelBase")
|
|
43
44
|
|
|
44
|
-
def __init__(self) -> None:
|
|
45
|
+
def __init__(self, auto_generate_projections: bool = True) -> None:
|
|
45
46
|
self.__projection_expression: str | None = None
|
|
46
47
|
self.__projection_expression_attribute_names: dict | None = None
|
|
47
48
|
self.__helpers: DynamoDBHelpers | None = None
|
|
48
49
|
self.__indexes: DynamoDBIndexes | None = None
|
|
50
|
+
self.__reserved_words: DynamoDBReservedWords = DynamoDBReservedWords()
|
|
51
|
+
self.auto_generate_projections: bool = auto_generate_projections
|
|
49
52
|
|
|
50
53
|
@property
|
|
51
54
|
@exclude_from_serialization
|
|
@@ -61,6 +64,14 @@ class DynamoDBModelBase:
|
|
|
61
64
|
@exclude_from_serialization
|
|
62
65
|
def projection_expression(self) -> str | None:
|
|
63
66
|
"""Gets the projection expression"""
|
|
67
|
+
if self.__projection_expression is None and self.auto_generate_projections:
|
|
68
|
+
props = self.to_dictionary()
|
|
69
|
+
# turn props to a list[str]
|
|
70
|
+
prop_list = list(props.keys())
|
|
71
|
+
|
|
72
|
+
transformed_list = self.__reserved_words.tranform_projections(prop_list)
|
|
73
|
+
self.projection_expression = ",".join(transformed_list)
|
|
74
|
+
|
|
64
75
|
return self.__projection_expression
|
|
65
76
|
|
|
66
77
|
@projection_expression.setter
|
|
@@ -70,7 +81,21 @@ class DynamoDBModelBase:
|
|
|
70
81
|
@property
|
|
71
82
|
@exclude_from_serialization
|
|
72
83
|
def projection_expression_attribute_names(self) -> dict | None:
|
|
73
|
-
"""
|
|
84
|
+
"""
|
|
85
|
+
Gets the projection expression attribute names
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
if (
|
|
89
|
+
self.__projection_expression_attribute_names is None
|
|
90
|
+
and self.auto_generate_projections
|
|
91
|
+
):
|
|
92
|
+
props = self.to_dictionary()
|
|
93
|
+
# turn props to a list[str]
|
|
94
|
+
prop_list = list(props.keys())
|
|
95
|
+
self.projection_expression_attribute_names = (
|
|
96
|
+
self.__reserved_words.transform_attributes(prop_list)
|
|
97
|
+
)
|
|
98
|
+
|
|
74
99
|
return self.__projection_expression_attribute_names
|
|
75
100
|
|
|
76
101
|
@projection_expression_attribute_names.setter
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DynamoDBReservedWords:
|
|
6
|
+
"""Reserved Word"""
|
|
7
|
+
|
|
8
|
+
def __init__(self) -> None:
|
|
9
|
+
self.__list: List[str] = self.__read_list()
|
|
10
|
+
|
|
11
|
+
def words(self) -> List[str]:
|
|
12
|
+
"""Gets a list of dynamodb reserved words"""
|
|
13
|
+
return self.__list
|
|
14
|
+
|
|
15
|
+
def __read_list(self) -> List[str]:
|
|
16
|
+
path = os.path.dirname(__file__)
|
|
17
|
+
path = os.path.join(path, "dynamodb_reserved_words.txt")
|
|
18
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
19
|
+
words = f.read().splitlines()
|
|
20
|
+
# make sure they are all in uppercase
|
|
21
|
+
for i, word in enumerate(words):
|
|
22
|
+
words[i] = word.upper()
|
|
23
|
+
return words
|
|
24
|
+
|
|
25
|
+
def is_reserved_word(self, word: str) -> bool:
|
|
26
|
+
"""Checks if a word is a dynamodb reserved word"""
|
|
27
|
+
return word.upper() in self.__list
|
|
28
|
+
|
|
29
|
+
def tranform_projections(self, projections: List[str] | str) -> List[str]:
|
|
30
|
+
"""Transforms a list of projections to remove reserved words"""
|
|
31
|
+
if isinstance(projections, str):
|
|
32
|
+
projections = projections.split(",")
|
|
33
|
+
|
|
34
|
+
# any project that exists add a # infront of it
|
|
35
|
+
projections = ["#" + p if self.is_reserved_word(p) else p for p in projections]
|
|
36
|
+
return projections
|
|
37
|
+
|
|
38
|
+
def transform_attributes(self, attributes: dict) -> dict:
|
|
39
|
+
"""Transforms a dict of attributes to remove reserved words"""
|
|
40
|
+
transformed_attributes: dict | None = {}
|
|
41
|
+
for k, v in attributes.items():
|
|
42
|
+
if self.is_reserved_word(k):
|
|
43
|
+
transformed_attributes["#" + k] = v
|
|
44
|
+
|
|
45
|
+
return transformed_attributes
|
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
|
|
2
|
+
ABORT
|
|
3
|
+
ABSOLUTE
|
|
4
|
+
ACTION
|
|
5
|
+
ADD
|
|
6
|
+
AFTER
|
|
7
|
+
AGENT
|
|
8
|
+
AGGREGATE
|
|
9
|
+
ALL
|
|
10
|
+
ALLOCATE
|
|
11
|
+
ALTER
|
|
12
|
+
ANALYZE
|
|
13
|
+
AND
|
|
14
|
+
ANY
|
|
15
|
+
ARCHIVE
|
|
16
|
+
ARE
|
|
17
|
+
ARRAY
|
|
18
|
+
AS
|
|
19
|
+
ASC
|
|
20
|
+
ASCII
|
|
21
|
+
ASENSITIVE
|
|
22
|
+
ASSERTION
|
|
23
|
+
ASYMMETRIC
|
|
24
|
+
AT
|
|
25
|
+
ATOMIC
|
|
26
|
+
ATTACH
|
|
27
|
+
ATTRIBUTE
|
|
28
|
+
AUTH
|
|
29
|
+
AUTHORIZATION
|
|
30
|
+
AUTHORIZE
|
|
31
|
+
AUTO
|
|
32
|
+
AVG
|
|
33
|
+
BACK
|
|
34
|
+
BACKUP
|
|
35
|
+
BASE
|
|
36
|
+
BATCH
|
|
37
|
+
BEFORE
|
|
38
|
+
BEGIN
|
|
39
|
+
BETWEEN
|
|
40
|
+
BIGINT
|
|
41
|
+
BINARY
|
|
42
|
+
BIT
|
|
43
|
+
BLOB
|
|
44
|
+
BLOCK
|
|
45
|
+
BOOLEAN
|
|
46
|
+
BOTH
|
|
47
|
+
BREADTH
|
|
48
|
+
BUCKET
|
|
49
|
+
BULK
|
|
50
|
+
BY
|
|
51
|
+
BYTE
|
|
52
|
+
CALL
|
|
53
|
+
CALLED
|
|
54
|
+
CALLING
|
|
55
|
+
CAPACITY
|
|
56
|
+
CASCADE
|
|
57
|
+
CASCADED
|
|
58
|
+
CASE
|
|
59
|
+
CAST
|
|
60
|
+
CATALOG
|
|
61
|
+
CHAR
|
|
62
|
+
CHARACTER
|
|
63
|
+
CHECK
|
|
64
|
+
CLASS
|
|
65
|
+
CLOB
|
|
66
|
+
CLOSE
|
|
67
|
+
CLUSTER
|
|
68
|
+
CLUSTERED
|
|
69
|
+
CLUSTERING
|
|
70
|
+
CLUSTERS
|
|
71
|
+
COALESCE
|
|
72
|
+
COLLATE
|
|
73
|
+
COLLATION
|
|
74
|
+
COLLECTION
|
|
75
|
+
COLUMN
|
|
76
|
+
COLUMNS
|
|
77
|
+
COMBINE
|
|
78
|
+
COMMENT
|
|
79
|
+
COMMIT
|
|
80
|
+
COMPACT
|
|
81
|
+
COMPILE
|
|
82
|
+
COMPRESS
|
|
83
|
+
CONDITION
|
|
84
|
+
CONFLICT
|
|
85
|
+
CONNECT
|
|
86
|
+
CONNECTION
|
|
87
|
+
CONSISTENCY
|
|
88
|
+
CONSISTENT
|
|
89
|
+
CONSTRAINT
|
|
90
|
+
CONSTRAINTS
|
|
91
|
+
CONSTRUCTOR
|
|
92
|
+
CONSUMED
|
|
93
|
+
CONTINUE
|
|
94
|
+
CONVERT
|
|
95
|
+
COPY
|
|
96
|
+
CORRESPONDING
|
|
97
|
+
COUNT
|
|
98
|
+
COUNTER
|
|
99
|
+
CREATE
|
|
100
|
+
CROSS
|
|
101
|
+
CUBE
|
|
102
|
+
CURRENT
|
|
103
|
+
CURSOR
|
|
104
|
+
CYCLE
|
|
105
|
+
DATA
|
|
106
|
+
DATABASE
|
|
107
|
+
DATE
|
|
108
|
+
DATETIME
|
|
109
|
+
DAY
|
|
110
|
+
DEALLOCATE
|
|
111
|
+
DEC
|
|
112
|
+
DECIMAL
|
|
113
|
+
DECLARE
|
|
114
|
+
DEFAULT
|
|
115
|
+
DEFERRABLE
|
|
116
|
+
DEFERRED
|
|
117
|
+
DEFINE
|
|
118
|
+
DEFINED
|
|
119
|
+
DEFINITION
|
|
120
|
+
DELETE
|
|
121
|
+
DELIMITED
|
|
122
|
+
DEPTH
|
|
123
|
+
DEREF
|
|
124
|
+
DESC
|
|
125
|
+
DESCRIBE
|
|
126
|
+
DESCRIPTOR
|
|
127
|
+
DETACH
|
|
128
|
+
DETERMINISTIC
|
|
129
|
+
DIAGNOSTICS
|
|
130
|
+
DIRECTORIES
|
|
131
|
+
DISABLE
|
|
132
|
+
DISCONNECT
|
|
133
|
+
DISTINCT
|
|
134
|
+
DISTRIBUTE
|
|
135
|
+
DO
|
|
136
|
+
DOMAIN
|
|
137
|
+
DOUBLE
|
|
138
|
+
DROP
|
|
139
|
+
DUMP
|
|
140
|
+
DURATION
|
|
141
|
+
DYNAMIC
|
|
142
|
+
EACH
|
|
143
|
+
ELEMENT
|
|
144
|
+
ELSE
|
|
145
|
+
ELSEIF
|
|
146
|
+
EMPTY
|
|
147
|
+
ENABLE
|
|
148
|
+
END
|
|
149
|
+
EQUAL
|
|
150
|
+
EQUALS
|
|
151
|
+
ERROR
|
|
152
|
+
ESCAPE
|
|
153
|
+
ESCAPED
|
|
154
|
+
EVAL
|
|
155
|
+
EVALUATE
|
|
156
|
+
EXCEEDED
|
|
157
|
+
EXCEPT
|
|
158
|
+
EXCEPTION
|
|
159
|
+
EXCEPTIONS
|
|
160
|
+
EXCLUSIVE
|
|
161
|
+
EXEC
|
|
162
|
+
EXECUTE
|
|
163
|
+
EXISTS
|
|
164
|
+
EXIT
|
|
165
|
+
EXPLAIN
|
|
166
|
+
EXPLODE
|
|
167
|
+
EXPORT
|
|
168
|
+
EXPRESSION
|
|
169
|
+
EXTENDED
|
|
170
|
+
EXTERNAL
|
|
171
|
+
EXTRACT
|
|
172
|
+
FAIL
|
|
173
|
+
FALSE
|
|
174
|
+
FAMILY
|
|
175
|
+
FETCH
|
|
176
|
+
FIELDS
|
|
177
|
+
FILE
|
|
178
|
+
FILTER
|
|
179
|
+
FILTERING
|
|
180
|
+
FINAL
|
|
181
|
+
FINISH
|
|
182
|
+
FIRST
|
|
183
|
+
FIXED
|
|
184
|
+
FLATTERN
|
|
185
|
+
FLOAT
|
|
186
|
+
FOR
|
|
187
|
+
FORCE
|
|
188
|
+
FOREIGN
|
|
189
|
+
FORMAT
|
|
190
|
+
FORWARD
|
|
191
|
+
FOUND
|
|
192
|
+
FREE
|
|
193
|
+
FROM
|
|
194
|
+
FULL
|
|
195
|
+
FUNCTION
|
|
196
|
+
FUNCTIONS
|
|
197
|
+
GENERAL
|
|
198
|
+
GENERATE
|
|
199
|
+
GET
|
|
200
|
+
GLOB
|
|
201
|
+
GLOBAL
|
|
202
|
+
GO
|
|
203
|
+
GOTO
|
|
204
|
+
GRANT
|
|
205
|
+
GREATER
|
|
206
|
+
GROUP
|
|
207
|
+
GROUPING
|
|
208
|
+
HANDLER
|
|
209
|
+
HASH
|
|
210
|
+
HAVE
|
|
211
|
+
HAVING
|
|
212
|
+
HEAP
|
|
213
|
+
HIDDEN
|
|
214
|
+
HOLD
|
|
215
|
+
HOUR
|
|
216
|
+
IDENTIFIED
|
|
217
|
+
IDENTITY
|
|
218
|
+
IF
|
|
219
|
+
IGNORE
|
|
220
|
+
IMMEDIATE
|
|
221
|
+
IMPORT
|
|
222
|
+
IN
|
|
223
|
+
INCLUDING
|
|
224
|
+
INCLUSIVE
|
|
225
|
+
INCREMENT
|
|
226
|
+
INCREMENTAL
|
|
227
|
+
INDEX
|
|
228
|
+
INDEXED
|
|
229
|
+
INDEXES
|
|
230
|
+
INDICATOR
|
|
231
|
+
INFINITE
|
|
232
|
+
INITIALLY
|
|
233
|
+
INLINE
|
|
234
|
+
INNER
|
|
235
|
+
INNTER
|
|
236
|
+
INOUT
|
|
237
|
+
INPUT
|
|
238
|
+
INSENSITIVE
|
|
239
|
+
INSERT
|
|
240
|
+
INSTEAD
|
|
241
|
+
INT
|
|
242
|
+
INTEGER
|
|
243
|
+
INTERSECT
|
|
244
|
+
INTERVAL
|
|
245
|
+
INTO
|
|
246
|
+
INVALIDATE
|
|
247
|
+
IS
|
|
248
|
+
ISOLATION
|
|
249
|
+
ITEM
|
|
250
|
+
ITEMS
|
|
251
|
+
ITERATE
|
|
252
|
+
JOIN
|
|
253
|
+
KEY
|
|
254
|
+
KEYS
|
|
255
|
+
LAG
|
|
256
|
+
LANGUAGE
|
|
257
|
+
LARGE
|
|
258
|
+
LAST
|
|
259
|
+
LATERAL
|
|
260
|
+
LEAD
|
|
261
|
+
LEADING
|
|
262
|
+
LEAVE
|
|
263
|
+
LEFT
|
|
264
|
+
LENGTH
|
|
265
|
+
LESS
|
|
266
|
+
LEVEL
|
|
267
|
+
LIKE
|
|
268
|
+
LIMIT
|
|
269
|
+
LIMITED
|
|
270
|
+
LINES
|
|
271
|
+
LIST
|
|
272
|
+
LOAD
|
|
273
|
+
LOCAL
|
|
274
|
+
LOCALTIME
|
|
275
|
+
LOCALTIMESTAMP
|
|
276
|
+
LOCATION
|
|
277
|
+
LOCATOR
|
|
278
|
+
LOCK
|
|
279
|
+
LOCKS
|
|
280
|
+
LOG
|
|
281
|
+
LOGED
|
|
282
|
+
LONG
|
|
283
|
+
LOOP
|
|
284
|
+
LOWER
|
|
285
|
+
MAP
|
|
286
|
+
MATCH
|
|
287
|
+
MATERIALIZED
|
|
288
|
+
MAX
|
|
289
|
+
MAXLEN
|
|
290
|
+
MEMBER
|
|
291
|
+
MERGE
|
|
292
|
+
METHOD
|
|
293
|
+
METRICS
|
|
294
|
+
MIN
|
|
295
|
+
MINUS
|
|
296
|
+
MINUTE
|
|
297
|
+
MISSING
|
|
298
|
+
MOD
|
|
299
|
+
MODE
|
|
300
|
+
MODIFIES
|
|
301
|
+
MODIFY
|
|
302
|
+
MODULE
|
|
303
|
+
MONTH
|
|
304
|
+
MULTI
|
|
305
|
+
MULTISET
|
|
306
|
+
NAME
|
|
307
|
+
NAMES
|
|
308
|
+
NATIONAL
|
|
309
|
+
NATURAL
|
|
310
|
+
NCHAR
|
|
311
|
+
NCLOB
|
|
312
|
+
NEW
|
|
313
|
+
NEXT
|
|
314
|
+
NO
|
|
315
|
+
NONE
|
|
316
|
+
NOT
|
|
317
|
+
NULL
|
|
318
|
+
NULLIF
|
|
319
|
+
NUMBER
|
|
320
|
+
NUMERIC
|
|
321
|
+
OBJECT
|
|
322
|
+
OF
|
|
323
|
+
OFFLINE
|
|
324
|
+
OFFSET
|
|
325
|
+
OLD
|
|
326
|
+
ON
|
|
327
|
+
ONLINE
|
|
328
|
+
ONLY
|
|
329
|
+
OPAQUE
|
|
330
|
+
OPEN
|
|
331
|
+
OPERATOR
|
|
332
|
+
OPTION
|
|
333
|
+
OR
|
|
334
|
+
ORDER
|
|
335
|
+
ORDINALITY
|
|
336
|
+
OTHER
|
|
337
|
+
OTHERS
|
|
338
|
+
OUT
|
|
339
|
+
OUTER
|
|
340
|
+
OUTPUT
|
|
341
|
+
OVER
|
|
342
|
+
OVERLAPS
|
|
343
|
+
OVERRIDE
|
|
344
|
+
OWNER
|
|
345
|
+
PAD
|
|
346
|
+
PARALLEL
|
|
347
|
+
PARAMETER
|
|
348
|
+
PARAMETERS
|
|
349
|
+
PARTIAL
|
|
350
|
+
PARTITION
|
|
351
|
+
PARTITIONED
|
|
352
|
+
PARTITIONS
|
|
353
|
+
PATH
|
|
354
|
+
PERCENT
|
|
355
|
+
PERCENTILE
|
|
356
|
+
PERMISSION
|
|
357
|
+
PERMISSIONS
|
|
358
|
+
PIPE
|
|
359
|
+
PIPELINED
|
|
360
|
+
PLAN
|
|
361
|
+
POOL
|
|
362
|
+
POSITION
|
|
363
|
+
PRECISION
|
|
364
|
+
PREPARE
|
|
365
|
+
PRESERVE
|
|
366
|
+
PRIMARY
|
|
367
|
+
PRIOR
|
|
368
|
+
PRIVATE
|
|
369
|
+
PRIVILEGES
|
|
370
|
+
PROCEDURE
|
|
371
|
+
PROCESSED
|
|
372
|
+
PROJECT
|
|
373
|
+
PROJECTION
|
|
374
|
+
PROPERTY
|
|
375
|
+
PROVISIONING
|
|
376
|
+
PUBLIC
|
|
377
|
+
PUT
|
|
378
|
+
QUERY
|
|
379
|
+
QUIT
|
|
380
|
+
QUORUM
|
|
381
|
+
RAISE
|
|
382
|
+
RANDOM
|
|
383
|
+
RANGE
|
|
384
|
+
RANK
|
|
385
|
+
RAW
|
|
386
|
+
READ
|
|
387
|
+
READS
|
|
388
|
+
REAL
|
|
389
|
+
REBUILD
|
|
390
|
+
RECORD
|
|
391
|
+
RECURSIVE
|
|
392
|
+
REDUCE
|
|
393
|
+
REF
|
|
394
|
+
REFERENCE
|
|
395
|
+
REFERENCES
|
|
396
|
+
REFERENCING
|
|
397
|
+
REGEXP
|
|
398
|
+
REGION
|
|
399
|
+
REINDEX
|
|
400
|
+
RELATIVE
|
|
401
|
+
RELEASE
|
|
402
|
+
REMAINDER
|
|
403
|
+
RENAME
|
|
404
|
+
REPEAT
|
|
405
|
+
REPLACE
|
|
406
|
+
REQUEST
|
|
407
|
+
RESET
|
|
408
|
+
RESIGNAL
|
|
409
|
+
RESOURCE
|
|
410
|
+
RESPONSE
|
|
411
|
+
RESTORE
|
|
412
|
+
RESTRICT
|
|
413
|
+
RESULT
|
|
414
|
+
RETURN
|
|
415
|
+
RETURNING
|
|
416
|
+
RETURNS
|
|
417
|
+
REVERSE
|
|
418
|
+
REVOKE
|
|
419
|
+
RIGHT
|
|
420
|
+
ROLE
|
|
421
|
+
ROLES
|
|
422
|
+
ROLLBACK
|
|
423
|
+
ROLLUP
|
|
424
|
+
ROUTINE
|
|
425
|
+
ROW
|
|
426
|
+
ROWS
|
|
427
|
+
RULE
|
|
428
|
+
RULES
|
|
429
|
+
SAMPLE
|
|
430
|
+
SATISFIES
|
|
431
|
+
SAVE
|
|
432
|
+
SAVEPOINT
|
|
433
|
+
SCAN
|
|
434
|
+
SCHEMA
|
|
435
|
+
SCOPE
|
|
436
|
+
SCROLL
|
|
437
|
+
SEARCH
|
|
438
|
+
SECOND
|
|
439
|
+
SECTION
|
|
440
|
+
SEGMENT
|
|
441
|
+
SEGMENTS
|
|
442
|
+
SELECT
|
|
443
|
+
SELF
|
|
444
|
+
SEMI
|
|
445
|
+
SENSITIVE
|
|
446
|
+
SEPARATE
|
|
447
|
+
SEQUENCE
|
|
448
|
+
SERIALIZABLE
|
|
449
|
+
SESSION
|
|
450
|
+
SET
|
|
451
|
+
SETS
|
|
452
|
+
SHARD
|
|
453
|
+
SHARE
|
|
454
|
+
SHARED
|
|
455
|
+
SHORT
|
|
456
|
+
SHOW
|
|
457
|
+
SIGNAL
|
|
458
|
+
SIMILAR
|
|
459
|
+
SIZE
|
|
460
|
+
SKEWED
|
|
461
|
+
SMALLINT
|
|
462
|
+
SNAPSHOT
|
|
463
|
+
SOME
|
|
464
|
+
SOURCE
|
|
465
|
+
SPACE
|
|
466
|
+
SPACES
|
|
467
|
+
SPARSE
|
|
468
|
+
SPECIFIC
|
|
469
|
+
SPECIFICTYPE
|
|
470
|
+
SPLIT
|
|
471
|
+
SQL
|
|
472
|
+
SQLCODE
|
|
473
|
+
SQLERROR
|
|
474
|
+
SQLEXCEPTION
|
|
475
|
+
SQLSTATE
|
|
476
|
+
SQLWARNING
|
|
477
|
+
START
|
|
478
|
+
STATE
|
|
479
|
+
STATIC
|
|
480
|
+
STATUS
|
|
481
|
+
STORAGE
|
|
482
|
+
STORE
|
|
483
|
+
STORED
|
|
484
|
+
STREAM
|
|
485
|
+
STRING
|
|
486
|
+
STRUCT
|
|
487
|
+
STYLE
|
|
488
|
+
SUB
|
|
489
|
+
SUBMULTISET
|
|
490
|
+
SUBPARTITION
|
|
491
|
+
SUBSTRING
|
|
492
|
+
SUBTYPE
|
|
493
|
+
SUM
|
|
494
|
+
SUPER
|
|
495
|
+
SYMMETRIC
|
|
496
|
+
SYNONYM
|
|
497
|
+
SYSTEM
|
|
498
|
+
TABLE
|
|
499
|
+
TABLESAMPLE
|
|
500
|
+
TEMP
|
|
501
|
+
TEMPORARY
|
|
502
|
+
TERMINATED
|
|
503
|
+
TEXT
|
|
504
|
+
THAN
|
|
505
|
+
THEN
|
|
506
|
+
THROUGHPUT
|
|
507
|
+
TIME
|
|
508
|
+
TIMESTAMP
|
|
509
|
+
TIMEZONE
|
|
510
|
+
TINYINT
|
|
511
|
+
TO
|
|
512
|
+
TOKEN
|
|
513
|
+
TOTAL
|
|
514
|
+
TOUCH
|
|
515
|
+
TRAILING
|
|
516
|
+
TRANSACTION
|
|
517
|
+
TRANSFORM
|
|
518
|
+
TRANSLATE
|
|
519
|
+
TRANSLATION
|
|
520
|
+
TREAT
|
|
521
|
+
TRIGGER
|
|
522
|
+
TRIM
|
|
523
|
+
TRUE
|
|
524
|
+
TRUNCATE
|
|
525
|
+
TTL
|
|
526
|
+
TUPLE
|
|
527
|
+
TYPE
|
|
528
|
+
UNDER
|
|
529
|
+
UNDO
|
|
530
|
+
UNION
|
|
531
|
+
UNIQUE
|
|
532
|
+
UNIT
|
|
533
|
+
UNKNOWN
|
|
534
|
+
UNLOGGED
|
|
535
|
+
UNNEST
|
|
536
|
+
UNPROCESSED
|
|
537
|
+
UNSIGNED
|
|
538
|
+
UNTIL
|
|
539
|
+
UPDATE
|
|
540
|
+
UPPER
|
|
541
|
+
URL
|
|
542
|
+
USAGE
|
|
543
|
+
USE
|
|
544
|
+
USER
|
|
545
|
+
USERS
|
|
546
|
+
USING
|
|
547
|
+
UUID
|
|
548
|
+
VACUUM
|
|
549
|
+
VALUE
|
|
550
|
+
VALUED
|
|
551
|
+
VALUES
|
|
552
|
+
VARCHAR
|
|
553
|
+
VARIABLE
|
|
554
|
+
VARIANCE
|
|
555
|
+
VARINT
|
|
556
|
+
VARYING
|
|
557
|
+
VIEW
|
|
558
|
+
VIEWS
|
|
559
|
+
VIRTUAL
|
|
560
|
+
VOID
|
|
561
|
+
WAIT
|
|
562
|
+
WHEN
|
|
563
|
+
WHENEVER
|
|
564
|
+
WHERE
|
|
565
|
+
WHILE
|
|
566
|
+
WINDOW
|
|
567
|
+
WITH
|
|
568
|
+
WITHIN
|
|
569
|
+
WITHOUT
|
|
570
|
+
WORK
|
|
571
|
+
WRAPPED
|
|
572
|
+
WRITE
|
|
573
|
+
YEAR
|
|
574
|
+
ZONE
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.1.6'
|
|
@@ -5,87 +5,12 @@ MIT License. See Project Root for the license information.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import unittest
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import List, Dict
|
|
9
|
+
|
|
9
10
|
|
|
10
|
-
from src.boto3_assist.dynamodb.dynamodb_model_base import DynamoDBModelBase
|
|
11
11
|
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex
|
|
12
12
|
from src.boto3_assist.dynamodb.dynamodb_key import DynamoDBKey
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class User(DynamoDBModelBase):
|
|
16
|
-
"""User Model"""
|
|
17
|
-
|
|
18
|
-
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
id: Optional[str] = None, # pylint: disable=redefined-builtin
|
|
21
|
-
):
|
|
22
|
-
DynamoDBModelBase.__init__(self)
|
|
23
|
-
self.id: Optional[str] = id
|
|
24
|
-
self.first_name: Optional[str] = None
|
|
25
|
-
self.last_name: Optional[str] = None
|
|
26
|
-
self.age: Optional[int] = None
|
|
27
|
-
self.email: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
self.__setup_indexes()
|
|
30
|
-
|
|
31
|
-
def __setup_indexes(self):
|
|
32
|
-
primary_key: DynamoDBIndex = DynamoDBIndex(
|
|
33
|
-
index_name="primary_key",
|
|
34
|
-
partition_key=DynamoDBKey(
|
|
35
|
-
attribute_name="pk",
|
|
36
|
-
value=lambda: DynamoDBKey.build_key((("user", self.id))),
|
|
37
|
-
),
|
|
38
|
-
sort_key=DynamoDBKey(
|
|
39
|
-
attribute_name="sk",
|
|
40
|
-
value=lambda: DynamoDBKey.build_key(("user", self.id)),
|
|
41
|
-
),
|
|
42
|
-
)
|
|
43
|
-
self.indexes.add_primary(primary_key)
|
|
44
|
-
|
|
45
|
-
gsi0: DynamoDBIndex = DynamoDBIndex(
|
|
46
|
-
index_name="gsi0",
|
|
47
|
-
partition_key=DynamoDBKey(attribute_name="gsi0_pk", value="users#"),
|
|
48
|
-
sort_key=DynamoDBKey(
|
|
49
|
-
attribute_name="gsi0_sk",
|
|
50
|
-
value=lambda: DynamoDBKey.build_key(("email", self.email)),
|
|
51
|
-
),
|
|
52
|
-
)
|
|
53
|
-
self.indexes.add_secondary(gsi0)
|
|
54
|
-
|
|
55
|
-
gsi1: DynamoDBIndex = DynamoDBIndex(
|
|
56
|
-
index_name="gsi1",
|
|
57
|
-
partition_key=DynamoDBKey(attribute_name="gsi1_pk", value="users#"),
|
|
58
|
-
sort_key=DynamoDBKey(
|
|
59
|
-
attribute_name="gsi1_sk",
|
|
60
|
-
value=lambda: DynamoDBKey.build_key(
|
|
61
|
-
("lastname", self.last_name), ("firstname", self.first_name)
|
|
62
|
-
),
|
|
63
|
-
),
|
|
64
|
-
)
|
|
65
|
-
self.indexes.add_secondary(gsi1)
|
|
66
|
-
|
|
67
|
-
gsi2: DynamoDBIndex = DynamoDBIndex(
|
|
68
|
-
index_name="gsi2",
|
|
69
|
-
partition_key=DynamoDBKey(attribute_name="gsi2_pk", value="users#"),
|
|
70
|
-
sort_key=DynamoDBKey(
|
|
71
|
-
attribute_name="gsi2_sk",
|
|
72
|
-
value=lambda: DynamoDBKey.build_key(
|
|
73
|
-
("firstname", self.first_name), ("lastname", self.last_name)
|
|
74
|
-
),
|
|
75
|
-
),
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
self.indexes.add_secondary(gsi2)
|
|
79
|
-
|
|
80
|
-
# self.key_configs = key_configs
|
|
81
|
-
self.projection_expression = (
|
|
82
|
-
"id,first_name,last_name,email,tenant_id,#type,#status,"
|
|
83
|
-
"company_name,authorization,modified_datetime_utc"
|
|
84
|
-
)
|
|
85
|
-
self.projection_expression_attribute_names = {
|
|
86
|
-
"#status": "status",
|
|
87
|
-
"#type": "type",
|
|
88
|
-
}
|
|
13
|
+
from tests.dynamodb.models.user_model import User
|
|
89
14
|
|
|
90
15
|
|
|
91
16
|
class DynamoDBModelUnitTest(unittest.TestCase):
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from tests.dynamodb.models.user_model import User
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DynamoDBModeProjectionlUnitTest(unittest.TestCase):
|
|
14
|
+
"Serialization Tests"
|
|
15
|
+
|
|
16
|
+
def test_projection_expressions_transformation(self):
|
|
17
|
+
"""Test Basic Serlization"""
|
|
18
|
+
# Arrange
|
|
19
|
+
data = {
|
|
20
|
+
"id": "123456",
|
|
21
|
+
"first_name": "John",
|
|
22
|
+
"age": 30,
|
|
23
|
+
"email": "john@example.com",
|
|
24
|
+
"status": "active",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Act
|
|
28
|
+
model: User = User().map(data)
|
|
29
|
+
|
|
30
|
+
# Assert
|
|
31
|
+
|
|
32
|
+
self.assertEqual(model.first_name, "John")
|
|
33
|
+
self.assertEqual(model.age, 30)
|
|
34
|
+
self.assertEqual(model.email, "john@example.com")
|
|
35
|
+
self.assertIsInstance(model, User)
|
|
36
|
+
|
|
37
|
+
key = model.indexes.primary.key()
|
|
38
|
+
self.assertIsInstance(key, dict)
|
|
39
|
+
|
|
40
|
+
expressions = model.projection_expression
|
|
41
|
+
self.assertIsInstance(expressions, str)
|
|
42
|
+
|
|
43
|
+
# #type is in expression
|
|
44
|
+
self.assertIn("#type", expressions)
|
|
45
|
+
self.assertIn("#status", expressions)
|
|
46
|
+
|
|
47
|
+
print(expressions)
|
|
48
|
+
|
|
49
|
+
attribute_names = model.projection_expression_attribute_names
|
|
50
|
+
self.assertIsInstance(attribute_names, dict)
|
|
51
|
+
self.assertIn("#type", attribute_names)
|
|
52
|
+
self.assertIn("#status", attribute_names)
|
|
53
|
+
|
|
54
|
+
# "#type": "type" is in the dictionary
|
|
55
|
+
self.assertIn("type", attribute_names["#type"])
|
|
56
|
+
self.assertIn("status", attribute_names["#status"])
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional, List, Dict
|
|
8
|
+
|
|
9
|
+
from src.boto3_assist.dynamodb.dynamodb_model_base import DynamoDBModelBase
|
|
10
|
+
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex
|
|
11
|
+
from src.boto3_assist.dynamodb.dynamodb_key import DynamoDBKey
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class User(DynamoDBModelBase):
|
|
15
|
+
"""User Model"""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
id: Optional[str] = None, # pylint: disable=redefined-builtin
|
|
20
|
+
):
|
|
21
|
+
DynamoDBModelBase.__init__(self)
|
|
22
|
+
self.id: Optional[str] = id
|
|
23
|
+
self.first_name: Optional[str] = None
|
|
24
|
+
self.last_name: Optional[str] = None
|
|
25
|
+
self.age: Optional[int] = None
|
|
26
|
+
self.email: Optional[str] = None
|
|
27
|
+
# known reserved words
|
|
28
|
+
self.status: Optional[str] = None
|
|
29
|
+
|
|
30
|
+
self.__setup_indexes()
|
|
31
|
+
|
|
32
|
+
def __setup_indexes(self):
|
|
33
|
+
primary_key: DynamoDBIndex = DynamoDBIndex(
|
|
34
|
+
index_name="primary_key",
|
|
35
|
+
partition_key=DynamoDBKey(
|
|
36
|
+
attribute_name="pk",
|
|
37
|
+
value=lambda: DynamoDBKey.build_key((("user", self.id))),
|
|
38
|
+
),
|
|
39
|
+
sort_key=DynamoDBKey(
|
|
40
|
+
attribute_name="sk",
|
|
41
|
+
value=lambda: DynamoDBKey.build_key(("user", self.id)),
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
self.indexes.add_primary(primary_key)
|
|
45
|
+
|
|
46
|
+
gsi0: DynamoDBIndex = DynamoDBIndex(
|
|
47
|
+
index_name="gsi0",
|
|
48
|
+
partition_key=DynamoDBKey(attribute_name="gsi0_pk", value="users#"),
|
|
49
|
+
sort_key=DynamoDBKey(
|
|
50
|
+
attribute_name="gsi0_sk",
|
|
51
|
+
value=lambda: DynamoDBKey.build_key(("email", self.email)),
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
self.indexes.add_secondary(gsi0)
|
|
55
|
+
|
|
56
|
+
gsi1: DynamoDBIndex = DynamoDBIndex(
|
|
57
|
+
index_name="gsi1",
|
|
58
|
+
partition_key=DynamoDBKey(attribute_name="gsi1_pk", value="users#"),
|
|
59
|
+
sort_key=DynamoDBKey(
|
|
60
|
+
attribute_name="gsi1_sk",
|
|
61
|
+
value=lambda: DynamoDBKey.build_key(
|
|
62
|
+
("lastname", self.last_name), ("firstname", self.first_name)
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
self.indexes.add_secondary(gsi1)
|
|
67
|
+
|
|
68
|
+
gsi2: DynamoDBIndex = DynamoDBIndex(
|
|
69
|
+
index_name="gsi2",
|
|
70
|
+
partition_key=DynamoDBKey(attribute_name="gsi2_pk", value="users#"),
|
|
71
|
+
sort_key=DynamoDBKey(
|
|
72
|
+
attribute_name="gsi2_sk",
|
|
73
|
+
value=lambda: DynamoDBKey.build_key(
|
|
74
|
+
("firstname", self.first_name), ("lastname", self.last_name)
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
self.indexes.add_secondary(gsi2)
|
|
80
|
+
|
|
81
|
+
# self.key_configs = key_configs
|
|
82
|
+
self.projection_expression = (
|
|
83
|
+
"id,first_name,last_name,email,tenant_id,#type,#status,"
|
|
84
|
+
"company_name,authorization,modified_datetime_utc"
|
|
85
|
+
)
|
|
86
|
+
self.projection_expression_attribute_names = {
|
|
87
|
+
"#status": "status",
|
|
88
|
+
"#type": "type",
|
|
89
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.1.5'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.1.5 → boto3_assist-0.1.6}/examples/dynamodb/services/user_service_client_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/dynamodb/dynamodb_connection_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.1.5 → boto3_assist-0.1.6}/src/boto3_assist/utilities/serialization_utility.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|