DynamoDB UpdateItem in Python (boto3)
boto3 ti dà due client per questa chiamata e i due non sono d'accordo su cosa sia un numero. Il client di basso livello qui sotto invia e riceve JSON DynamoDB, dove ogni numero è una stringa fra virgolette. resource("dynamodb").Table(...) accetta oggetti Python nativi, rifiuta di netto float e restituisce i numeri come decimal.Decimal. Sceglierne uno è la vera decisione di questa pagina.
Codice
import boto3
client = boto3.client("dynamodb")
response = client.update_item(
TableName="Music",
Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
UpdateExpression="SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2",
ExpressionAttributeNames={"#upd0": "Genre", "#upd1": "Year", "#upd2": "Awards"},
ExpressionAttributeValues={":updValue0": {"S": "Latin Jazz"}, ":updValue1": {"N": "1994"}, ":updValue2": {"N": "1"}},
ReturnValues="ALL_NEW",
)
print(response["Attributes"]) # the item after the updateSpiegazione
- La grammatica delle clausole non è affar suo di boto3. L'
UpdateExpressionè una stringa opaca che si limita a inoltrare; solo DynamoDB la analizza, quindi gli errori costano un round trip.ADDqui è l'incremento atomico che elimina la corsa read-modify-write,attribute_exists(Artist)in unaConditionExpressiontrasforma l'upsert in un solo update, e il resto sta in update expression. - La risposta ha esattamente due chiavi di primo livello:
AttributeseResponseMetadata. Non c'è alcun campo di stato da controllare né un conteggio di righe. Se la chiamata è tornata, ha funzionato;ResponseMetadataporta ilRequestIde l'HTTPStatusCodeche vuoi in una riga di log. ReturnValues="UPDATED_NEW"è l'opzione parsimoniosa. Restituisce solo gli attributi toccati dall'espressione, il che su un Item grande è la differenza fra leggere un contatore e rispedire indietro l'intero record.- Gli errori arrivano come
botocore.exceptions.ClientError, e ramifichi sue.response["Error"]["Code"]. Un alias mancante produceValidationExceptioncon il messaggioInvalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: Year. Le sottoclassi tipizzate esistono, ma solo come attributi che botocore genera sull'istanza del client (client.exceptions.ConditionalCheckFailedException), mai come simboli importabili, quindi una funzione helper che non ha il client nello scope deve usare la stringa del codice.
Decimal o JSON DynamoDB, scegline uno
L'API resource rifiuta float prima ancora che la richiesta sia costruita, con un messaggio che ti dice esattamente cosa vuole:
TypeError: Float types are not supported. Use Decimal types instead.È il controllo di tipo di boto3, non di DynamoDB. Memorizza Decimal("4.5") attraverso l'API resource e rileggi lo stesso attributo attraverso entrambi i client, e ottieni:
resource Rating: Decimal('4.5') Awards: Decimal('2')
client Rating: {'N': '4.5'} Awards: {'N': '2'}Nessuno dei due è sbagliato; sono contratti diversi. Decimal mantiene la precisione che DynamoDB memorizza davvero e ti obbliga a ragionare sull'aritmetica, al prezzo di un Decimal("1") * 2 che spunta in codice che si aspettava un int. Il client di basso livello ti passa stringhe e lascia a te il parsing, che è quello che fa lo snippet qui sopra.
La regola che ne deriva: non mescolarli nello stesso percorso di codice. Un Item scritto attraverso Table.put_item e letto attraverso client.get_item torna indietro in una forma diversa, e il bug salta fuori nel ramo che hai testato meno.
Una nota sugli attributi TTL
Il SET numerico più comune in un codebase Python è un TTL: SET expires_at = :t con un epoch Unix. DynamoDB legge quell'attributo in secondi. Scrivi invece int(time.time() * 1000) e il valore è 1785269450912, che letto come secondi finisce nell'anno 58542, quindi l'Item non viene mai eliminato e nessuno protesta. Il convertitore TTL DynamoDB rilegge un epoch in entrambe le unità e ti dice quale hai scritto. Per rileggere poi il valore memorizzato da una tabella reale, scarica DynoTable.
Guide correlate
- Update expression di DynamoDB —
SET,ADD,REMOVE,DELETEe gli idiomi. - Capire ReturnValues — cosa ti dà ciascuna opzione di
ReturnValues. - "Attribute name is a reserved keyword" — perché la mappa di alias qui non è opzionale.
- Errori di sintassi "Invalid UpdateExpression" — i tipici errori di sintassi di SET/ADD, decodificati.
Riferimenti
- UpdateItem — Amazon DynamoDB API Reference
- update_item — Boto3 DynamoDB.Client Reference
- Update expressions — Amazon DynamoDB Developer Guide
Ultima verifica 2026-07-28 rispetto alla documentazione ufficiale AWS collegata sopra.