2016-04-21 47 views
10

私のテーブルは250kレコードで約220MBです。私はこのデータをすべて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() 

答えて

-1

Boto3が返された応答の一部として "LastEvaluatedKey"を取得することが分かります。これは、スキャンの開始点として使用することができます。

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

返されたデータのみをExclusiveStartKey

15

boto3はあなたのためのすべての改ページの詳細を処理paginatorsを提供していますまで、私はこの問題を回避ループを構築することを計画します。 Hereはスキャンページングのドキュメントページです。基本的には、次のように使用します:

import boto3 

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

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

注 'ページの[」内の項目ことアイテム '] 'はあなたが期待しているものではない可能性があります。このページネータは痛々しく一般的ですので、各DynamoDBアイテムで返されるものは、フォーマットタイプの辞書です。 '{'myAttribute':{'M':{}}、 'yourAttribute':{'N':u'132457 '}}'は、空のマップと数値型を持つ行です(これは、キャストする必要があります;これは 'decimal.Decimal'です。これは既に文字列を受け取り、非整数を扱うためです)。他のタイプ、例えば。文字列、マップ、およびブール値は、botoによってPythonの型に変換されます。 – kungphu

+0

は、ページングを使用してスキャンフィルタまたはfilterexpressionを持つ可能性はありますか? – vnpnlz

+0

@kungphuが問題を提起しなかった場合、ページめがねはすばらしいでしょう。私は有用なものは1つしかないが、レスポンスデータを無関係のメタデータで汚染することによってそれを無効にするものは使用しない。 –

4

@kungphuのようにdynamodbのフォーマットタイプを削除するコード。

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!上記の私の以前のコメントは、ページャーの有用性の欠如について否定しています。ありがとう!これはデフォルトの動作ではないのはなぜですか? –

11

テーブルスキャンに関する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 documentation](http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Client.query)の状態はLastEvaluatedKeyが空の場合、結果の「最後のページ」が処理され、検索するデータはもうありません。したがって、私が使用しているテストは '応答 '中の' LastEvaluatedKey'ではなくresponse.get( 'LastEvaluatedKey')ですが、単に「空である」とは必ずしも「存在しない」という意味ではなく、どちらの場合でも有効です。 – kungphu

+0

paginatorは照会/スキャンしたアイテムを繰り返し処理する方が便利です – iuriisusuk

4

、ここにあなたがページネーションとで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 
関連する問題