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

ens*_*are 9 python amazon-dynamodb

寻找一个从dynamodb中检索500个项目的简单示例,从而最大限度地减少查询次数.我知道有一个"多功能"功能可以让我把它分解成50个查询的块,但不知道如何做到这一点.

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

或者有更好的方法吗?

作为必然结果,我将如何"排序"之后的项目?

yad*_*taf 12

根据您的方案,有两种方法可以有效地检索您的500项.

1个项目是相同的hash_key,使用arange_key

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

2个项目在"随机"键上

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

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

遗憾的是,这些库都没有提供一种简单的方法来包装batch_get操作.相反,有一个生成器scan,用于query"假装"你在一个查询中得到所有.

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

  • 提交包含所有500件商品的批次.
  • 将结果存储在您的dicts中
  • 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
Run Code Online (Sandbox Code Playgroud)

编辑:

我已经添加了一个resubmit()功能,以BatchList在博托发展分支.它大大简化了工作流程:

  1. 所有请求的密钥添加到BatchList
  2. submit()
  3. resubmit() 只要它不返回None.

这应该在下一个版本中提供.