是否有用于向AWS DynamoDB提交批量获取请求的Python API?

Pau*_*gel 11 python amazon-web-services amazon-dynamodb boto3

该软件包boto3- 亚马逊用于python的官方AWS API包装器 - 非常支持批量上传项目到DynamoDB.它看起来像这样:

db = boto3.resource("dynamodb", region_name = "my_region").Table("my_table")

with db.batch_writer() as batch:
    for item in my_items:
        batch.put_item(Item = item)
Run Code Online (Sandbox Code Playgroud)

my_items是一个Python字典列表,每个字典都必须包含表的主键.情况并不完美 - 例如,没有安全机制来阻止您超出吞吐量限制 - 但它仍然相当不错.

但是,从数据库中读取似乎没有任何对应物.我能找到的最接近的是DynamoDB.Client.batch_get_item(),但这里的API非常复杂.这是请求两个项目的样子:

db_client = boto3.client("dynamodb", "my_region")

db_client.batch_get_item(
    RequestItems = {
        "my_table": {
            "Keys": [
                {"my_primary_key": {"S": "my_key1"}},
                {"my_primary_key": {"S": "my_key2"}}
            ]
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

这可能是可以容忍的,但是响应也存在同样的问题:所有值都是字典,其键是数据类型("S"对于字符串,"N"数字,"M"映射等),并且解析所有内容会有点烦人.所以我的问题是:

是否有任何原生boto3支持从DynamoDb批量读取,类似于batch_writer上面的功能?

没错,

是否boto3提供任何内置方法来自动反序列化对DynamoDB.Client.batch_get_item()函数的响应?

我还要补充说,该函数boto3.resource("dynamodb").Table().get_item()具有我认为的"正确"API,因为输入或输出不需要类型解析.所以这似乎是开发人员的某种疏忽,我想我正在寻找一种解决方法.

Abh*_*nan 7

因此,值得庆幸的是,您可能会发现有用的东西-就像json具有json.dumps和的模块一样json.loads,boto3的类型模块包含一个序列化器和反序列化器。请参阅TypeSerializer / TypeDeserializer。如果您查看源代码,则序列化/反序列化是递归的,并且对于您的用例而言应该是完美的。

注意:建议您使用Binary/ Decimal而不是仅使用常规的旧python float / int进行往返转换。

serializer = TypeSerializer()
serializer.serialize('awesome') # returns {'S' : 'awesome' }

deser = TypeDeserializer()
deser.deserialize({'S' : 'awesome'}) # returns u'awesome'
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助!


ElC*_*ine 5

服务资源级别为batch_get_item。也许您可以做这样的事情:

def batch_query_wrapper(table, key, values):

    results = []

    response = dynamo.batch_get_item(RequestItems={table: {'Keys': [{key: val} for val in values]}})
    results.extend(response['Responses'][table])

    while response['UnprocessedKeys']:

        # Implement some kind of exponential back off here
        response = dynamo.batch_get_item(RequestItems={table: {'Keys': [{key: val} for val in values]}})
        results.extend(response['Response'][table])

    return results
Run Code Online (Sandbox Code Playgroud)

它将以python对象的形式返回您的结果。