2016-06-17 10 views
5

Das Paket boto3 - Amazons offizieller AWS-API-Wrapper für Python - bietet großartige Unterstützung für das Hochladen von Elementen in DynamoDB. Es sieht wie folgt aus:Gibt es eine Python-API zum Senden von Batch-Get-Anforderungen an AWS DynamoDB?

db = boto3.resource("dynamodb", region_name = "my_region").Table("my_table") 

with db.batch_writer() as batch: 
    for item in my_items: 
     batch.put_item(Item = item) 

Hier my_items eine Liste von Python-Dictionaries ist, von denen jede den Tisch des Primärschlüssel haben muss (s). Die Situation ist nicht perfekt - zum Beispiel gibt es keinen Sicherheitsmechanismus, der Sie daran hindert, Ihre Durchsatzgrenzen zu überschreiten - aber es ist immer noch ziemlich gut.

Es scheint jedoch kein Gegenstück zum Lesen aus der Datenbank zu geben. Der nächste, den ich finden kann, ist DynamoDB.Client.batch_get_item(), aber hier ist die API extrem kompliziert. Hier ist, was Ihr Interesse an zwei Elementen wie folgt aussieht:

db_client = boto3.client("dynamodb", "my_region") 

db_client.batch_get_item(
    RequestItems = { 
     "my_table": { 
      "Keys": [ 
       {"my_primary_key": {"S": "my_key1"}}, 
       {"my_primary_key": {"S": "my_key2"}} 
      ] 
     } 
    } 
) 

Diese erträglich sein könnte, aber die Antwort hat das gleiche Problem: alle Werte sind Wörterbücher, deren Schlüssel Datentypen ("S" für string, "N" für Nummer, "M" zur Kartierung, etc.) und es ist mehr als ein bisschen nervig, alles parsen zu müssen. Also meine Fragen sind:

Gibt es einen nativen boto3 Unterstützung für Batch von DynamoDB Lesen, ähnlich der batch_writer Funktion oben?

dass Failing,

Bietet boto3 jede integrierte Möglichkeit, automatisch die Antworten auf die DynamoDB.Client.batch_get_item() Funktion deserialisieren?

Ich werde auch hinzufügen, dass die Funktion boto3.resource("dynamodb").Table().get_item() hat, was würde ich als der „richtige“ API sein, dass kein Typen-Parsing für Ein- oder Ausgänge erforderlich ist. Es scheint also, dass dies eine Art Versäumnis seitens der Entwickler ist, und ich denke, ich suche nach einem Workaround.

Antwort

2

So zum Glück ist es etwas, das Ihnen nützlich sein könnten - ähnlich wie die json Modul, das json.dumps und json.loads hat, hat boto3 ein Typen-Modul, das einen Serializer und Deserializer enthält. Siehe TypeSerializer/TypeDeserializer. Wenn Sie sich den Quellcode ansehen, ist die Serialisierung/Deserialisierung rekursiv und sollte für Ihren Anwendungsfall perfekt sein.

Hinweis: Es wird empfohlen, dass Sie Binary/Decimal statt nur eine normale alte Python float/int für Round-Trip-Konvertierungen verwenden.

serializer = TypeSerializer() 
serializer.serialize('awesome') # returns {'S' : 'awesome' } 

deser = TypeDeserializer() 
deser.deserialize({'S' : 'awesome'}) # returns u'awesome' 

Hoffentlich hilft das!

+0

das sieht gut aus! Ich denke, das wird die meisten Schmerzpunkte wegnehmen. Danke – mark

1

Es gibt die Service-Ressourcenstufe batch_get_item. Vielleicht könnten Sie so etwas tun:

def batch_query_wrapper(table, key, values): 

    results = [] 

    response = dynamo.batch_get_item(RequestItems={table: {'Keys': [{key: val} for val in values]}}) 
    results.extend(response['Responses'][table]) 

    while response['UnprocessedKeys']: 

     # Implement some kind of exponential back off here 
     response = dynamo.batch_get_item(RequestItems={table: {'Keys': [{key: val} for val in values]}}) 
     results.extend(response['Response'][table]) 

    return results 

Es wird Ihr Ergebnis als Python-Objekte zurück.