使用Python从dynamodb检索500个项目的简单示例

时间:2012-08-25 12:32:57

标签: python amazon-dynamodb

寻找一个从dynamodb中检索500个项目的简单示例,从而最大限度地减少查询次数。我知道有一个“多功能”功能可以让我将其分解为50个查询,但不知道如何执行此操作。

我从一个500键的列表开始。我正在考虑编写一个函数,它接受这个键列表,将其分解为“块”,检索值,将它们重新拼接在一起,然后返回500个键值对的字典。

或者有更好的方法吗?

作为必然结果,我之后如何“排序”这些项目?

1 个答案:

答案 0 :(得分:11)

根据您的计划,有两种方法可以有效地检索您的500件物品。

1项使用hash_key

位于同一range_key
  • query方法与hash_key
  • 一起使用
  • 您可能会要求对range_keys A-Z或Z-A
  • 进行排序

2个项目在“随机”键上

  • 您说过:使用BatchGetItem方法
  • 好消息:限制实际上是100 /请求或最大1MB
  • 你必须在Python方面对结果进行排序。

在实践方面,由于您使用Python,我强烈建议Boto library进行低级访问,或dynamodb-mapper library进行更高级访问(免责声明:我是dynamodb的核心开发人员之一)映射器)。

可悲的是,这些库都没有提供一种简单的方法来包装batch_get操作。相反,有一个scan生成器和query生成器,它可以“假装”您在一个查询中获得所有内容。

为了通过批量查询获得最佳结果,我建议使用此工作流程:

  • 提交包含所有500件物品的批次。
  • 将结果存储在您的词汇中
  • 根据需要使用UnprocessedKeys重新提交
  • 在python端对结果进行排序

快速示例

我假设你创建了一个带有hash_key

的表格“MyTable”
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开发分支added a resubmit() functionBatchList。它极大地简化了工作流程:

  1. 所有您要求的密钥添加到BatchList
  2. submit()
  3. resubmit()只要它不返回无。
  4. 这应该在下一个版本中提供。