web-dev-qa-db-ja.com

AWS DynamoDBにバッチ取得リクエストを送信するためのPython APIはありますか?

パッケージ_boto3_- python-のAmazonの公式AWSAPIラッパーは、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)
_

ここで、_my_items_はPython辞書のリストです。各辞書にはテーブルの主キーが必要です。状況は完全ではありません。たとえば、次のような安全メカニズムはありません。スループット制限を超えないようにしますが、それでもかなり良好です。

ただし、データベースから読み取るための対応物はないようです。私が見つけることができる最も近いものはDynamoDB.Client.batch_get_item()ですが、ここではAPIが非常に複雑です。 2つのアイテムをリクエストすると次のようになります。

_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"}}
            ]
        }
    }
)
_

これは許容できるかもしれませんが、応答には同じ問題があります。すべての値は、キーがデータ型である辞書です(文字列の場合は_"S"_、数値の場合は_"N"_、マッピングの場合は_"M"_など)。そして、すべてを解析しなければならないのは少し面倒です。だから私の質問は:

上記の_boto3_関数と同様に、DynamoDbからのバッチ読み取りに対するネイティブの_batch_writer_サポートはありますか?

それが失敗すると、

_boto3_は、DynamoDB.Client.batch_get_item()関数への応答を自動的に逆シリアル化する組み込みの方法を提供しますか?

また、関数boto3.resource("dynamodb").Table().get_item()には、入力または出力に型解析が必要ないという点で、「正しい」APIと見なされるものがあることも追加します。ですから、これは開発者によるある種の見落としのようであり、私は回避策を探していると思います。

15
Paul Siegel

ありがたいことに、便利なものがあります。json.dumpsjson.loadsを持つjsonモジュールのように、boto3にはシリアライザーとデシリアライザーを含むtypesモジュールがあります。 TypeSerializer/TypeDeserializer を参照してください。ソースコードを見ると、シリアル化/逆シリアル化は再帰的であり、ユースケースに最適であるはずです。

注:ラウンドトリップ変換に通常の古いpython float/intを使用するのではなく、Binary/Decimalを使用することをお勧めします。

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

deser = TypeDeserializer()
deser.deserialize({'S' : 'awesome'}) # returns u'awesome'

うまくいけば、これが役立ちます!

サービスリソースレベルがあります 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

結果をpythonオブジェクトとして返します。

4
ElCapitaine

これは、Boto 3DynamoDBアイテムをPython dictに変換する効果的な方法だと思います。

https://github.com/Alonreznik/dynamodb-json

1
dps