Vivek
Vivek

Reputation: 102

Why we have to specify the attribute type when use boto3 client and not in resource?

@app.route("/companies/<string:companyId>/<string:name>/")
def get_search(companyId,name):
    resp = client.get_item(
        TableName=COMPANIES_TABLE,
        Key={
            'companyId': { 'S': companyId },
            'name': { 'S': name }

        }
    )
    item = resp.get('Item')
    if not item:
        return jsonify({'error': 'Company does not exist'}), 404

    return jsonify({
        'companyId': item.get('companyId').get('S'),
        'name': item.get('name').get('S'),
        'region': item.get('region').get('S')
    })

The response from a DynamoDB resource object looks doesn't require me to parse the low level data structure from DynamoDB, but when I use the boto3 client I have to do that, why is that?

response = table.scan(
    FilterExpression=Attr('name').eq(name)
        )
    item = response['Items']
    import pdb;pdb.set_trace()
    if not item:
        return jsonify({'error': 'Company does not exist'}), 404

    return jsonify({
        'companyId': item.get('companyId'),
        'name': item.get('name'),
        'region': item.get('region')
    })

Upvotes: 1

Views: 758

Answers (1)

Maurice
Maurice

Reputation: 13108

In general the resource API in boto3 is a higher level abstraction from the underlying client API. It tries to hide some of the implementation details of the underlying client calls, but comes at a performance cost.

You can also use the deserializer that comes with boto3 to turn the values from client.get_item() into a Python object.

from boto3.dynamodb.types import TypeDeserializer

def main():
    dynamodb_item = {
        "PK": {
            "S": "key"
        },
        "SK": {
            "S": "value"
        }
    }

    deserializer = TypeDeserializer()
    
    deserialized = {
        key: deserializer.deserialize(dynamodb_item[key])
        for key in dynamodb_item.keys()
    }

    print(deserialized) # {'PK': 'key', 'SK': 'value'}

if __name__ == "__main__":
    main()

Upvotes: 2

Related Questions