10

寻找一个从 dynamodb 中检索 500 个项目以最小化查询数量的简单示例。我知道有一个“multiget”函数可以让我将其分解为 50 个查询的块,但不知道如何执行此操作。

我从 500 个键的列表开始。然后我正在考虑编写一个函数来获取这个键列表,将其分解为“块”,检索值,将它们缝合在一起,并返回 500 个键值对的字典。

还是有更好的方法来做到这一点?

作为推论,之后我将如何“分类”这些项目?

4

1 回答 1

12

根据您的计划,有 2 种方法可以有效地检索您的 500 个项目。

1 项目相同hash_key,使用range_key

  • 使用该query方法与hash_key
  • 您可能会要求对range_keysAZ 或 ZA进行排序

2 项目在“随机”键上

  • 你说的:使用BatchGetItem方法
  • 好消息:限制实际上是 100/request 或 1MB max
  • 您将不得不在 Python 端对结果进行排序。

在实际方面,由于您使用 Python,我强烈推荐用于低级访问的Boto 库或用于高级访问的 dynamodb-mapper 库(免责声明:我是 dynamodb-mapper 的核心开发人员之一)。

遗憾的是,这些库都没有提供包装 batch_get 操作的简单方法。相反,有一个生成器用于scanquery假装”你在一个查询中得到所有信息。

为了通过批处理查询获得最佳结果,我推荐这个工作流程:

  • 提交包含所有 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()只要它不返回无。

这应该在下一个版本中可用。

于 2012-08-27T14:52:01.690 回答