使用boto3完成对dynamoDB的完整扫描。

6 浏览
0 Comments

使用boto3完成对dynamoDB的完整扫描。

我的表格大约有220MB,其中包含250,000条记录。我想将所有数据导入Python。我意识到这需要一个分批处理的过程,并且需要循环遍历,但我不确定如何设置批次从上一批次结束的地方开始。\n有没有办法过滤我的扫描?根据我所读的,过滤发生在加载之后,加载在1MB处停止,所以我实际上无法扫描新对象。\n任何帮助将不胜感激。\n

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()

0
0 Comments

问题的原因是boto3的paginators在处理DynamoDB的扫描操作时返回的数据格式不符合预期。解决方法是使用TypeDeserializer来转换数据类型。

boto3是一个Python的AWS SDK,提供了许多用于操作Amazon Web Services的功能。其中包括对DynamoDB的操作。在处理DynamoDB的扫描操作时,boto3提供了一个Paginator类来处理分页的细节,方便用户进行数据的遍历操作。

具体的使用方法如下:

import boto3
client = boto3.client('dynamodb')
paginator = client.get_paginator('scan')
for page in paginator.paginate():
    # do something

上述代码中,首先导入boto3库,并创建一个DynamoDB的client对象。然后通过client对象的get_paginator方法创建一个Paginator对象,指定操作为scan。接下来使用Paginator对象的paginate方法进行分页操作,遍历每一页的数据进行处理。

需要注意的是,由于Paginator类是通用的,返回的数据格式可能不符合预期。每个DynamoDB的item都以字典的形式返回,其格式为type: value,例如{'myAttribute': {'M': {}}, 'yourAttribute': {'N': u'132457'}}。其中,'M'表示一个空map,'N'表示一个数值类型(以字符串形式返回,需要转换为数值类型)。其他类型,如字符串、map和布尔值,会被boto3转换为对应的Python类型。

原帖中还提到了一个问题,就是Paginator返回的数据中包含了一些无关的元数据,这使得数据处理起来变得困难。原帖的作者考虑切换到使用DynamoDB的resource而非client,并使用LastEvaluatedKey来进行分页操作,这样可以避免处理Paginator返回的数据。

不过,原帖的作者在后来发现了一个解决方法,即使用TypeDeserializer类来转换数据类型。TypeDeserializer是boto3提供的一个辅助类,可以将DynamoDB的item转换为Python对象。作者在stackoverflow上找到了一个示例代码,链接如下:stackoverflow.com/a/46738251/923817

最后,原帖中还有其他用户对此问题的回复,其中某些情况下自己最近在使用Clojure开发,在处理Amazon的API时遇到的问题要少得多。这说明虽然boto3提供了便捷的操作接口,但在处理DynamoDB的扫描操作时仍然存在一些不便之处。

0
0 Comments

问题的出现的原因是DynamoDB的scan方法对每次扫描的数据限制为1MB。这意味着如果表中的数据超过1MB,一次扫描将无法返回所有的数据。

为了解决这个问题,可以使用LastEvaluatedKey来获取DynamoDB表中的所有数据。上述代码提供了一个示例循环,使用LastEvaluatedKey来获取表中的所有数据,并将结果存储在一个列表中。

具体解决方法如下:

1. 导入boto3库,创建DynamoDB的客户端对象。

import boto3
client = boto3.client('dynamodb')

2. 创建一个函数dump_table,并传入表名作为参数。

def dump_table(table_name):

3. 初始化一个空列表results用于存储所有的数据。

results = []

4. 初始化一个变量last_evaluated_key,用于存储上一次扫描的最后一个键。

last_evaluated_key = None

5. 使用循环来不断扫描表中的数据,直到所有数据都被获取。

while True:

6. 判断last_evaluated_key是否存在,如果存在,则使用scan方法扫描表,并设置ExclusiveStartKey参数为上一次扫描的最后一个键。

if last_evaluated_key:

response = client.scan(TableName=table_name, ExclusiveStartKey=last_evaluated_key)

7. 如果last_evaluated_key不存在,则使用scan方法扫描表。

else:

response = client.scan(TableName=table_name)

8. 获取扫描结果中的LastEvaluatedKey,并更新last_evaluated_key的值。

last_evaluated_key = response.get('LastEvaluatedKey')

9. 将扫描结果中的Items添加到results列表中。

results.extend(response['Items'])

10. 判断last_evaluated_key是否为空,如果为空,则跳出循环。

if not last_evaluated_key:

break

11. 返回最终的结果列表results

return results

12. 使用dump_table函数来获取表中的所有数据,并将结果存储在data变量中。

data = dump_table('your-table-name')

13. 最后,可以对获取到的数据data进行后续处理。

0
0 Comments

完整扫描 DynamoDB 并使用 boto3 的原因及解决方法

在使用 boto3 进行 DynamoDB 的扫描操作时,可能会遇到需要完整扫描整个表的情况。以下是一个关于如何处理这种情况的问题的原因和解决方法。

根据 Amazon DynamoDB 文档,关于表扫描的回答了你的问题。

简而言之,需要在响应中检查 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'])

虽然这段代码可以工作,但是需要注意 boto3 文档 中的说明:如果 LastEvaluatedKey 为空,则表示已处理完“最后一页”的结果,没有更多数据可获取。 所以我使用的测试条件是 while response.get('LastEvaluatedKey') 而不是 while 'LastEvaluatedKey' in response,因为“为空”并不一定意味着“不存在”,这种方法在任何情况下都有效。

另外,使用 paginator 是更方便的遍历查询/扫描项目的方式。

response.get('LastEvaluatedKey')

我得到了 None,无法将它应用于 while 循环。

_J 提供了另一种解决方法,可以使用 while True:,然后使用 if not response.get('LastEvaluatedKey'): break 或类似的方法。你还可以将处理过程封装在一个函数中,调用该函数,然后使用上面的 while response.get(...): 来调用函数以处理后续页面。基本上,你只需要模拟 Python 中并不存在的 do... while 循环。

为什么不使用 while response.get('LastEvaluatedKey', False)

这样也可以工作,但并不必要。.get 默认情况下会返回 None,如果请求的键不存在,则 None 会被转换为 False。可以通过运行 bool({}.get('test')) 来确认这一点。

以上是关于如何解决完整扫描 DynamoDB 表的问题的原因和解决方法。

0