Boto3: Dynamodb client query behaves differently depending on whether it is a new client or it comes from the resource

Created on 11 Sep 2019  路  5Comments  路  Source: boto/boto3

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
closing-soon dynamodb

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

All 5 comments

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.

Was this page helpful?
0 / 5 - 0 ratings