用boto3完整扫描dynamoDb

问题描述:

我的表格大约是220MB,其中有250k条记录。我试图把所有这些数据都放到python中。我意识到这需要分块批处理并循环通过,但我不确定如何将批处理设置为开始之前离开的位置。用boto3完整扫描dynamoDb

有什么方法可以过滤我的扫描吗?从我读的过滤发生在加载和加载停止在1MB,所以我实际上不能够扫描新的对象。

任何援助将不胜感激。

import boto3 
dynamodb = boto3.resource('dynamodb', 
    aws_session_token = aws_session_token, 
    aws_access_key_id = aws_access_key_id, 
    aws_secret_access_key = aws_secret_access_key, 
    region_name = region 
    ) 

table = dynamodb.Table('widgetsTableName') 

data = table.scan() 

原来,Boto3捕获“LastEvaluatedKey”作为返回响应的一部分。这可以被用来作为起始点扫描:

data= table.scan(
    ExclusiveStartKey=data['LastEvaluatedKey'] 
) 

我计划建立解决此一循环,直到返回的数据仅是ExclusiveStartKey

boto3提供了处理所有分页细节为你paginators 。 Here是扫描分页器的文档页面。基本上,你会这样使用它:

import boto3 

client = boto3.client('dynamodb') 
paginator = client.get_paginator('scan') 

for page in paginator.paginate(): 
    # do something 
+2

注意,在'页[”项目Items']'可能不是您所期望的:由于此分页程序非常通用,因此每个DynamoDB项目都会返回一个格式类型的字典:value,例如'{'myAttribute':{'M':{}},'yourAttribute':{'N':u'132457'}}'对于一个空映射和一个数字类型的行需要被强制转换;我建议'decimal.Decimal',因为它已经接受了一个字符串并且会处理非整数)。其他类型,例如字符串,地图和布尔值,由boto转换为它们的Python类型。 – kungphu

+0

是否有扫描过滤器或filterexpression与分页? – vnpnlz

+0

paginators会很棒,如果它不是针对@kungphu提出的问题。我没有看到用它来做一件有用的事情,但是通过用无关的元数据污染响应数据来抵消它。 –

代码删除dynamodb格式类型为@ kungphu提到。

import boto3 

from boto3.dynamodb.types import TypeDeserializer 
from boto3.dynamodb.transform import TransformationInjector 

client = boto3.client('dynamodb') 
paginator = client.get_paginator('query') 
service_model = client._service_model.operation_model('Query') 
trans = TransformationInjector(deserializer = TypeDeserializer()) 
for page in paginator.paginate(): 
    trans.inject_attribute_value_output(page, service_model) 
+0

Bravo!否定了我之前关于paginators缺乏实用性的评论。谢谢!为什么这不是默认行为? –

我认为Amazon DynamoDB documentation关于表扫描回答你的问题。

总之,您需要检查LastEvaluatedKey的响应。下面是使用你的代码的例子:

import boto3 
dynamodb = boto3.resource('dynamodb', 
          aws_session_token=aws_session_token, 
          aws_access_key_id=aws_access_key_id, 
          aws_secret_access_key=aws_secret_access_key, 
          region_name=region 
) 

table = dynamodb.Table('widgetsTableName') 

response = table.scan() 
data = response['Items'] 

while 'LastEvaluatedKey' in response: 
    response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey']) 
    data.extend(response['Items']) 
+7

尽管这可能有效,请注意[boto3文档](http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Client.query)状态_If LastEvaluatedKey为空,则结果的“最后一页”已被处理,并且没有更多数据需要检索。因此,我正在使用的测试是'while response.get('LastEvaluatedKey')'而不是'while'LastEvaluatedKey'in response',仅仅因为“是空的”并不一定意味着“不存在”,并且这在任何情况下都起作用。 – kungphu

+0

paginator是遍历查询/扫描项目更方便的方式 – iuriisusuk

Riffing关闭佐敦菲利普斯的回答,这就是你要如何传递FilterExpression与分页:

import boto3 

client = boto3.client('dynamodb') 
paginator = client.get_paginator('scan') 
operation_parameters = { 
    'TableName': 'foo', 
    'FilterExpression': 'bar > :x AND bar < :y', 
    'ExpressionAttributeValues': { 
    ':x': {'S': '2017-01-31T01:35'}, 
    ':y': {'S': '2017-01-31T02:08'}, 
    } 
} 

page_iterator = paginator.paginate(**operation_parameters) 
for page in page_iterator: 
    # do something