2015-07-08 12 views
8

Sto usando DynamoDB come db K-V (perché non ci sono molti dati, penso che vada bene), e parte di "V" è il tipo di lista (circa 10 elementi). C'è qualche sessione per aggiungere un nuovo valore ad esso, e non riesco a trovare un modo per farlo in una sola richiesta. Quello che ho fatto è stato questo:Come aggiungere un valore per elencare l'attributo su AWS DynamoDB?

item = self.list_table.get_item(**{'k': 'some_key'}) 
item['v'].append('some_value') 
item.partial_save() 

Chiedo prima il server e lo salvo dopo aver modificato il valore. Non è atomico e sembra brutto. C'è un modo per farlo in una richiesta?

risposta

3

È possibile eseguire questa operazione in 1 richiesta utilizzando l'API UpdateItem insieme a uno UpdateExpression. Dal momento che si desidera aggiungere a un elenco, si può usare l'azione SET con la funzione list_append:

SET supporta le seguenti funzioni:

...

  • list_append (operand, operand) - restituisce un elencare con un nuovo elemento aggiunto. È possibile aggiungere il nuovo elemento all'inizio o alla fine dell'elenco invertendo l'ordine degli operandi.

Si può vedere un paio di esempi di questo sul Modifying Items and Attributes with Update Expressions documentation:

  • L'esempio seguente aggiunge un nuovo elemento alla lista di revisione FiveStar. Il nome dell'attributo dell'espressione #pr è ProductReviews; l'attributo valore :r è un elenco di un elemento. Se in precedenza l'elenco contiene due elementi , [0] e [1], il nuovo elemento sarà [2].

    SET #pr.FiveStar = list_append(#pr.FiveStar, :r) 
    
  • L'esempio seguente aggiunge un altro elemento alla FiveStar recensione lista, ma questa volta l'elemento verrà aggiunto alla l'inizio della lista a [0]. Tutti gli altri elementi nell'elenco verranno spostati di uno .

    SET #pr.FiveStar = list_append(:r, #pr.FiveStar) 
    

Il #pr e :r stanno usando segnaposti per i nomi ei valori degli attributi. È possibile visualizzare ulteriori informazioni su quelli su Using Placeholders for Attribute Names and Values documentation.

+0

Ma non ho trovato alcuna API boto ... – kxxoling

24

Il seguente codice dovrebbe funzionare con boto3:

table = get_dynamodb_resource().Table("table_name") 
result = table.update_item(
    Key={ 
     'hash_key': hash_key, 
     'range_key': range_key 
    }, 
    UpdateExpression="SET some_attr = list_append(some_attr, :i)", 
    ExpressionAttributeValues={ 
     ':i': [some_value], 
    }, 
    ReturnValues="UPDATED_NEW" 
) 
if result['ResponseMetadata']['HTTPStatusCode'] == 200 and 'Attributes' in result: 
    return result['Attributes']['some_attr'] 

Il metodo get_dynamodb_resource qui è solo:

def get_dynamodb_resource(): 
    return boto3.resource(
      'dynamodb', 
      region_name=os.environ['AWS_DYNAMO_REGION'], 
      endpoint_url=os.environ['AWS_DYNAMO_ENDPOINT'], 
      aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'], 
      aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID']) 
+0

grazie! questo funziona perfettamente. Anche se ho provato ad usare ADD ma non ha funzionato. Ho letto nei documenti che raccomandano l'uso di ADD. Quando ho provato a utilizzare ADD, ho ottenuto errore di corrispondenza operatore in UpdateExpression. – kishorer747

+0

Molto utile! Scusa posso solo fare +1 :( – vnpnlz

+0

l'elemento della lista deve esistere? O posso solo usare questo e init_a_a_a_a_a_a_a_a_a_it_it per me come una lista vuota se non esistesse? – Jonathan

Problemi correlati