10

クエリの数を最小限に抑えて、dynamodb から 500 個のアイテムを取得する簡単な例を探しています。これを 50 個のクエリのチャンクに分割できる "multiget" 関数があることは知っていますが、これを行う方法がわかりません。

500 個のキーのリストから始めます。次に、このキーのリストを取得し、それを「チャンク」に分割し、値を取得してそれらをつなぎ合わせ、500 個のキーと値のペアの辞書を返す関数を作成することを考えています。

または、これを行うより良い方法はありますか?

当然のことながら、後でアイテムをどのように「ソート」しますか?

4

1 に答える 1

12

スキームに応じて、500 個のアイテムを効率的に取得するには 2 つの方法があります。

1 個のアイテムが同じ の下にありhash_keyrange_key

  • queryメソッドをhash_key
  • range_keysAZまたはZAをソートするように依頼することができます

2 項目が「ランダム」キーにある

  • あなたはそれを言いました:BatchGetItemメソッドを使用してください
  • 朗報: 制限は実際には 100/リクエストまたは最大 1MB です
  • Python 側で結果をソートする必要があります。

実用面では、Python を使用しているため、低レベル アクセスにはBoto ライブラリを、高レベル アクセスにはdynamodb-mapper ライブラリを強くお勧めします (免責事項: 私は dynamodb-mapper のコア開発者の 1 人です)。

残念ながら、これらのライブラリのどちらも、batch_get 操作をラップする簡単な方法を提供していません。それどころか、単一のクエリですべてを取得する「ふりをする」scanためのジェネレーターがあります。query

バッチ クエリで最適な結果を得るには、次のワークフローをお勧めします。

  • 500 個のアイテムすべてを含むバッチを送信します。
  • 結果を辞書に保存します
  • UnprocessedKeys必要な回数だけ再提出する
  • Python側で結果を並べ替える

簡単な例

単一のテーブル「MyTable」を作成したと仮定しますhash_key

import boto

# Helper function. This is more or less the code
# I added to devolop branch
def resubmit(batch, prev):
    # Empty (re-use) the batch
    del batch[:]

    # The batch answer contains the list of
    # unprocessed keys grouped by tables
    if 'UnprocessedKeys' in prev:
        unprocessed = res['UnprocessedKeys']
    else:
        return None

    # Load the unprocessed keys
    for table_name, table_req in unprocessed.iteritems():
        table_keys = table_req['Keys']
        table = batch.layer2.get_table(table_name)

        keys = []
        for key in table_keys:
            h = key['HashKeyElement']
            r = None
            if 'RangeKeyElement' in key:
                r = key['RangeKeyElement']
            keys.append((h, r))

        attributes_to_get = None
        if 'AttributesToGet' in table_req:
            attributes_to_get = table_req['AttributesToGet']

        batch.add_batch(table, keys, attributes_to_get=attributes_to_get)

    return batch.submit()

# Main
db = boto.connect_dynamodb()
table = db.get_table('MyTable')
batch = db.new_batch_list()

keys = range (100) # Get items from 0 to 99

batch.add_batch(table, keys)

res = batch.submit()

while res:
    print res # Do some usefull work here
    res = resubmit(batch, res)

# The END

編集:

Boto開発ブランチに関数追加しました。resubmit()BatchListワークフローが大幅に簡素化されます。

  1. 要求されたすべてのキーをに追加しますBatchList
  2. submit()
  3. resubmit()None を返さない限り。

これは次のリリースで利用可能になるはずです。

于 2012-08-27T14:52:01.690 に答える