I have a parameters variable
params = {
"TableName": "name_of_table",
"KeyConditionExpression": "user_id = :user_id",
"ExpressionAttributeValues": {
":user_id": { "S": "username" }
},
}
I also created a client
client = boto3.client("dynamodb")
and ran
client.query(**params)
which returns the correct data from our table. But when we create a resource
resource = boto3.resource("dynamodb")
and run
resource.meta.client.query(**params)
I get the error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the Query operation: One or more parameter values were invalid: Condition parameter type does not match schema type
It looks like client.query requires the attribute values to be in the encoded format, i.e. ":user_id": { "S": "username" }
but the resource.meta.client.query requires it to be uncoded, i.e. ":user_id": "username"
EDIT: The documentation leads me to believe that it should be encoded in both cases
Thank you for your post. @jg75 - is right. When using with resource you have to use ExpressionAttributeValues like this ":user_id": "username".
Here is the link for examples showing how to use boto3 resource with Dynamodb:
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html
I'm not sure the documentation is quite right. It looks like if you do table.query the values should be unencoded and the table parameter is not needed (makes sense). If you created a client and do a query, but the values should be encoded and it needs a table parameter (makes sense). If you get the resource.meta.client and do a query the value needs to be unencoded and needs a table parameter (something is off here)
This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.
I think you missed his point. I believe it is fair to expect that boto3.client('dynamodb') and boto3.resource('dynamodb').meta.client should behave the same way and his example demonstrate that it is not the case.
Most helpful comment
It looks like client.query requires the attribute values to be in the encoded format, i.e.
":user_id": { "S": "username" }but the resource.meta.client.query requires it to be uncoded, i.e.
":user_id": "username"EDIT: The documentation leads me to believe that it should be encoded in both cases