2016-04-21 16 views
10

La mia tabella è di circa 220 MB con 250 k di record al suo interno. Sto cercando di recuperare tutti questi dati in python. Mi rendo conto che questo deve essere un processo batch bannato e ripetuto, ma non sono sicuro di come sia possibile impostare i batch in modo che inizino da dove era rimasto il precedente.Scansione completa di dynamoDb con boto3

C'è qualche modo per filtrare la mia scansione? Da quello che ho letto il filtro si verifica dopo il caricamento e il caricamento si interrompe a 1 MB, quindi non sarei in grado di eseguire la scansione di nuovi oggetti.

Qualsiasi assistenza sarebbe gradita.

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

risposta

-1

scopre che Boto3 cattura il "LastEvaluatedKey" come parte della risposta restituita. Questo può essere usato come punto di partenza per una scansione:

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

Ho intenzione di costruire un anello attorno a questo fino a quando i dati restituiti sono solo l'ExclusiveStartKey

15

boto3 offre paginators che gestiscono tutti i dettagli impaginazione per voi . Here è la pagina doc per lo scan paginator. In sostanza, si usa in questo modo:

import boto3 

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

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

Nota che i prodotti in 'pagina [' Gli elementi "]" potrebbero non essere ciò che ti aspetti: poiché questo cercapersone è dolorosamente generico, quello che riceverai per ogni articolo di DynamoDB è un dizionario di tipo formato: valore, ad esempio '{'myAttribute': {'M': {}}, 'yourAttribute': {'N': u'132457 '}}' per una riga con una mappa vuota e un tipo numerico (che viene restituito come una stringa che deve essere lanciato, io suggerisco 'decimal.Decimal' per questo poiché prende già una stringa e gestirà i numeri non interi). Altri tipi, ad es. stringhe, mappe e booleani, vengono convertiti nei loro tipi Python da boto. – kungphu

+0

è possibile avere un filtro di scansione o limerexpressione con impaginazione? Gli spettatori – vnpnlz

+0

sarebbero fantastici, se non fosse per il problema sollevato da @kungphu. Non vedo l'uso per qualcosa che fa una cosa utile, ma la nega inquinando i dati di risposta con metadati irrilevanti –

4

codice per l'eliminazione di DynamoDB tipo di formato come @kungphu menzionato.

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! nega il mio precedente commento sopra sulla mancanza di utilità degli impaginatori. Grazie! Perché questo non è il comportamento predefinito? –

11

credo che la quanto riguarda la scansione tavolo Amazon DynamoDB documentation risponde alla tua domanda.

In breve, è necessario verificare la presenza di LastEvaluatedKey nella risposta. Ecco un esempio utilizzando il codice:

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

Sebbene ciò possa funzionare, si noti che la [documentazione di boto3] (http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Client.query) afferma _If LastEvaluatedKey è vuoto, quindi il "ultima pagina" dei risultati è stata elaborata e non ci sono più dati da recuperare. Quindi il test che sto usando è 'while response.get ('LastEvaluatedKey')' piuttosto che 'while 'LastEvaluatedKey' in response', solo perché "è vuoto" non significa necessariamente "non è presente", e ciò funziona in entrambi i casi. – kungphu

+0

paginator è il modo più conveniente per scorrere gli oggetti interrogati/scansionati – iuriisusuk

4

riffing off di risposta di Jordon Phillips, ecco come ci si passa un FilterExpression con l'impaginazione:

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 
Problemi correlati