@@ -10,29 +10,17 @@ class ResourceShapeToClientShapeConverter:
10
10
def __init__ (self , table_name = None ):
11
11
self .boto3_converter = InternalBoto3DynamoDBFormatConverter (
12
12
item_handler = TypeSerializer ().serialize ,
13
- condition_handler = self ._unpack_built_condition_expression2
13
+ condition_handler = self .condition_handler
14
14
)
15
15
self .table_name = table_name
16
16
self .expression_builder = InternalDBESDKDynamoDBConditionExpressionBuilder ()
17
17
18
- def _unpack_built_condition_expression (self , request_to_update , expression_key ):
19
- built_condition_expression = request_to_update [expression_key ]
20
- request_to_update [expression_key ] = built_condition_expression .condition_expression
21
- attribute_names_from_built_expression = built_condition_expression .attribute_name_placeholders
22
- # Join any placeholder ExpressionAttributeNames with any other ExpressionAttributeNames
23
- try :
24
- request_to_update ["ExpressionAttributeNames" ] = request_to_update ["ExpressionAttributeNames" ] | attribute_names_from_built_expression
25
- except KeyError :
26
- request_to_update ["ExpressionAttributeNames" ] = attribute_names_from_built_expression
27
- # BuiltConditionExpression stores values in resource format; convert to client format before joining
28
- attribute_values_from_built_expression = dict_to_ddb (built_condition_expression .attribute_value_placeholders )
29
- try :
30
- request_to_update ["ExpressionAttributeValues" ] = request_to_update ["ExpressionAttributeValues" ] | attribute_values_from_built_expression
31
- except KeyError :
32
- request_to_update ["ExpressionAttributeValues" ] = attribute_values_from_built_expression
33
-
34
- def _unpack_built_condition_expression2 (self , expression_key , request ):
18
+ def condition_handler (self , expression_key , request ):
19
+ """Converts an object from boto3.dynamodb.conditions to a string
20
+ and updates ExpressionAttributeNames and ExpressionAttributeValues with any new names/values.
21
+ The ExpressionAttributeValues are returned in resource format (Python dictionaries)."""
35
22
condition_expression = request [expression_key ]
23
+
36
24
try :
37
25
existing_expression_attribute_names = request ["ExpressionAttributeNames" ]
38
26
except KeyError :
@@ -42,19 +30,28 @@ def _unpack_built_condition_expression2(self, expression_key, request):
42
30
except KeyError :
43
31
existing_expression_attribute_values = {}
44
32
33
+ # Only convert if the condition expression is a boto3.dynamodb.conditions object.
34
+ # Resources also accept strings.
35
+ # If condition is not from boto3.dynamodb.conditions, assume the condition is string-like, and return as-is.
45
36
if hasattr (condition_expression , "__module__" ) and condition_expression .__module__ == "boto3.dynamodb.conditions" :
46
37
built_condition_expression = self .expression_builder .build_expression (condition_expression , existing_expression_attribute_names , existing_expression_attribute_values )
47
38
else :
48
39
return condition_expression , existing_expression_attribute_names , existing_expression_attribute_values
49
40
41
+ # Unpack returned BuiltConditionExpression.
50
42
expression_str = built_condition_expression .condition_expression
51
43
attribute_names_from_built_expression = built_condition_expression .attribute_name_placeholders
52
- # Join any placeholder ExpressionAttributeNames with any other ExpressionAttributeNames
44
+ # Join any placeholder ExpressionAttributeNames with any other ExpressionAttributeNames.
45
+ # The BuiltConditionExpression will return new names, not any that already exist.
46
+ # The two sets of names must be joined to form the complete set of names for the condition expression.
53
47
try :
54
48
out_names = request ["ExpressionAttributeNames" ] | attribute_names_from_built_expression
55
49
except KeyError :
56
50
out_names = attribute_names_from_built_expression
57
- # BuiltConditionExpression stores values in resource format; convert to client format before joining
51
+ # Join existing and new values.
52
+ # BuiltConditionExpression returns values in resource format, but the request provides values in client format.
53
+ # The Smithy-generated code will handle converting the values from client to resource format.
54
+ # Convert the values to client format before joining.
58
55
attribute_values_from_built_expression = dict_to_ddb (built_condition_expression .attribute_value_placeholders )
59
56
try :
60
57
out_values = request ["ExpressionAttributeValues" ] | attribute_values_from_built_expression
@@ -63,60 +60,32 @@ def _unpack_built_condition_expression2(self, expression_key, request):
63
60
64
61
return expression_str , out_names , out_values
65
62
66
- def item (self , item ):
67
- return dict_to_ddb (item )
68
-
69
- def key_to_attribute_value_map (self , key_to_attribute_value ):
70
- return dict_to_ddb (key_to_attribute_value )
71
-
72
- def attribute_value (self , attribute_value ):
73
- serializer = TypeSerializer ()
74
- return serializer .serialize (attribute_value )
75
-
76
- # def put_item_request(self, put_item_request):
77
- # if not self.table_name:
78
- # raise ValueError("Table name must be provided to ResourceShapeToClientShapeConverter to use put_item")
79
- # put_item_request["TableName"] = self.table_name
80
- # super_conversion = super().put_item_request(put_item_request)
81
- # if "ConditionExpression" in super_conversion and isinstance(super_conversion["ConditionExpression"], BuiltConditionExpression):
82
- # self._unpack_built_condition_expression(super_conversion, "ConditionExpression")
83
- # return super_conversion
84
-
85
63
def put_item_request (self , put_item_request ):
64
+ # put_item requests on a boto3.resource.Table require a configured table name.
86
65
if not self .table_name :
87
66
raise ValueError ("Table name must be provided to ResourceShapeToClientShapeConverter to use put_item" )
88
67
put_item_request ["TableName" ] = self .table_name
89
68
return self .boto3_converter .PutItemInput (put_item_request )
90
- # if "ConditionExpression" in super_conversion and isinstance(super_conversion["ConditionExpression"], BuiltConditionExpression):
91
- # self._unpack_built_condition_expression(super_conversion, "ConditionExpression")
92
-
69
+
93
70
def get_item_request (self , get_item_request ):
71
+ # get_item requests on a boto3.resource.Table require a configured table name.
94
72
if not self .table_name :
95
73
raise ValueError ("Table name must be provided to ResourceShapeToClientShapeConverter to use get_item" )
96
74
get_item_request ["TableName" ] = self .table_name
97
- # return super().get_item_request(get_item_request)
98
75
return self .boto3_converter .GetItemInput (get_item_request )
99
76
100
77
def query_request (self , query_request ):
78
+ # query requests on a boto3.resource.Table require a configured table name.
101
79
if not self .table_name :
102
80
raise ValueError ("Table name must be provided to ResourceShapeToClientShapeConverter to use query" )
103
81
query_request ["TableName" ] = self .table_name
104
- # super_conversion = super().query_request(query_request)
105
- # if "KeyConditionExpression" in super_conversion and isinstance(super_conversion["KeyConditionExpression"], BuiltConditionExpression):
106
- # self._unpack_built_condition_expression(super_conversion, "KeyConditionExpression")
107
- # if "FilterExpression" in super_conversion and isinstance(super_conversion["FilterExpression"], BuiltConditionExpression):
108
- # self._unpack_built_condition_expression(super_conversion, "FilterExpression")
109
- # return super_conversion
110
82
return self .boto3_converter .QueryInput (query_request )
111
83
112
84
def scan_request (self , scan_request ):
85
+ # scan requests on a boto3.resource.Table require a configured table name.
113
86
if not self .table_name :
114
87
raise ValueError ("Table name must be provided to ResourceShapeToClientShapeConverter to use scan" )
115
88
scan_request ["TableName" ] = self .table_name
116
- # super_conversion = super().scan_request(scan_request)
117
- # if "FilterExpression" in super_conversion and isinstance(super_conversion["FilterExpression"], BuiltConditionExpression):
118
- # self._unpack_built_condition_expression(super_conversion, "FilterExpression")
119
- # return super_conversion
120
89
return self .boto3_converter .ScanInput (scan_request )
121
90
122
91
def transact_get_items_request (self , transact_get_items_request ):
@@ -154,53 +123,3 @@ def get_item_response(self, get_item_response):
154
123
155
124
def put_item_response (self , put_item_response ):
156
125
return self .boto3_converter .PutItemOutput (put_item_response )
157
-
158
-
159
-
160
-
161
- # def expression(self, condition_expression, expression_attribute_names, expression_attribute_values):
162
- # # Expressions provided to tables can be Condition objects, which need to be converted to strings.
163
- # if hasattr(condition_expression, "__module__") and condition_expression.__module__ == "boto3.dynamodb.conditions":
164
- # out = self.expression_builder.build_expression(condition_expression, expression_attribute_names, expression_attribute_values)
165
- # return out
166
- # # Expressions provided to tables can also already be string-like.
167
- # # Assume the user has provided something string-like, and let Smithy-Python/DBESDK internals raise exceptions if not.
168
- # print(f"probably a string: {condition_expression=}")
169
- # return condition_expression
170
-
171
- # def batch_write_item_request_items(self, tables):
172
- # """Transform a batch write request's items to DynamoDB format."""
173
- # output_tables = {}
174
- # table_names = list(tables.keys())
175
- # for table_name in table_names:
176
- # requests = tables[table_name]
177
- # output_requests = []
178
- # for request in requests:
179
- # request_name_list = list(request.keys())
180
- # if len(request_name_list) > 1:
181
- # raise ValueError("Invalid JSON format")
182
- # request_name = request_name_list[0]
183
- # if request_name == "PutRequest":
184
- # dict_request = dict_to_ddb(request[request_name]["Item"])
185
- # boto3_request = {"Item": dict_request}
186
- # elif request_name == "DeleteRequest":
187
- # # Delete requests are based on Keys, which are expected to already be in DynamoDB JSON.
188
- # # Only Items can be in Python dictionary JSON.
189
- # boto3_request = request[request_name]
190
- # else:
191
- # raise ValueError(f"Unknown batch_write_items method key: {request_name}")
192
- # output_requests.append({request_name: boto3_request})
193
- # output_tables[table_name] = output_requests
194
- # return output_tables
195
-
196
- # def batch_get_request(self, **kwargs):
197
- # """Transform a batch get request to DynamoDB format."""
198
- # dynamodb_input = kwargs.copy()
199
- # tables = dynamodb_input["RequestItems"]
200
-
201
- # for table_name, table_data in tables.items():
202
- # dynamodb_input["RequestItems"][table_name]["Keys"] = [
203
- # self.key_to_attribute_value_map(key) for key in table_data["Keys"]
204
- # ]
205
-
206
- # return dynamodb_input
0 commit comments