为什么我们必须在使用 boto3 客户端而不是在资源中指定属性类型?

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')
    })

来自 DynamoDB 资源对象的响应看起来不需要我解析来自 DynamoDB 的低级数据结构,但是当我使用 boto3 客户端时我必须这样做,这是为什么?

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')
    })

一般来说,boto3 中的 resource API 是对底层 client API 的更高层次的抽象。它试图隐藏底层客户端调用的一些实现细节,但会以性能成本为代价。

您还可以使用 boto3 附带的反序列化器将 client.get_item() 中的值转换为 Python 对象。

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()