Intermedio5 min di lettura

Espressione DynamoDB Nomi e valori Attributo

Le espressioni DynamoDB sono modelli: scrivi i segnaposto, quindi fornisci il reale Nomi e valori in due mappe laterali. #name è un segnaposto del nome; :value è un segnaposto di valore. Confondi i due e DynamoDB rifiuta il intera chiamata.

Qual è la differenza tra #name e :value in DynamoDB?

#name è un segnaposto per un attributo nome, fornito tramite ExpressionAttributeNames; :value è un segnaposto per un attributo valore, fornito tramite ExpressionAttributeValues. Utilizza #name per evitare parole, punti o spazi riservati e :value per ogni valore letterale: DynamoDB non incorpora mai valori. Non sono intercambiabili; scambiandoli si genera un ValidationException.

  • #name sostituisce il nome di un attributo tramite ExpressionAttributeNames — utilizzare it ogni volta che un attributo entra in conflitto con una parola riservata o contiene un punto/space.
  • :value sostituisce un valore tramite ExpressionAttributeValues — DynamoDB non incorpora mai i valori letterali nel testo dell'espressione, quindi ogni valore è un segnaposto.
  • Non sono intercambiabili. Un # a cui appartiene un : è un ValidationException, non un no-op silenzioso.

Provenendo da SQL, li inline entrambi: WHERE status = 'published'. DynamoDB in linea neanche. Quella divisione è la cosa che fa inciampare ogni nuovo arrivato.

Perché esistono le due mappe

In SQL la stringa di query trasporta tutto: nomi di colonne, valori letterali, operatori. DynamoDB separa deliberatamente la forma dell'espressione dai suoi dati.

I valori vanno nella propria mappa in modo che DynamoDB possa digitarli ciascuno (S, N, BOOL, ...) e quindi il parser non deve mai indovinare dove finisce una stringa: non ci sono virgolette o scappare per sbagliare. Vedere tipi di dati in DynamoDB per l'elenco completo dei tag di tipo.

I nomi ricevono lo stesso trattamento per un motivo diverso: DynamoDB ha un lungo elenco di parole riservate e qualsiasi attributo corrispondente non può apparire come un semplice nome in un'espressione. Il segnaposto evita completamente la prenotazione.

La trappola delle parole riservate

Ecco una tabella di articoli CMS: chiave di partizione BLOG#<blog>, chiave di ordinamento ARTICLE#<slug>: i cui attributi vengono letti in modo naturale ma con i quali capita di scontrarsi parole riservate:

AttributoPrenotato?Cosa contiene
statusdraft / published
namenome visualizzato dell'autore
sizelunghezza in byte renderizzati
ttlscadenza archivio (epoca)
slugnoLumaca URL

status, name, size e ttl sono tutti nell'elenco delle parole riservate di AWS, quindi questo il filtro fallisce sulla prima parola:

FilterExpression  status = :s

DynamoDB restituisce un ValidationException"Il nome Attributo è riservato parola chiave; parola chiave riservata: status". La soluzione è un nome segnaposto, mai rinominando l'attributo:

FilterExpression           #status = :s
ExpressionAttributeNames   { "#status": "status" }
ExpressionAttributeValues  { ":s": { "S": "published" } }

slug_non_ è riservato, quindi una query che hai testato suslugfunziona, e tu presumo che lo farà anche il prossimo. Quindistatus` lo rompe. L'elenco completo si sposta, quindi non memorizzarlo: segnaposto ogni nome e non verrai mai morso.

Mappa ogni valore, sempre

I valori non sono negoziabili: non esiste una sintassi per un letterale inline. Anche una pianura il numero ottiene un segnaposto. Questo aggiornamento contrassegna un articolo pubblicato, lo timbra dimensione e imposta un archivio di 30 giorni :

UpdateExpression:          SET #status = :s, #size = :sz, #ttl = :exp
ExpressionAttributeNames:  { "#status": "status", "#size": "size", "#ttl": "ttl" }
ExpressionAttributeValues: {
  ":s":   { "S": "published" },
  ":sz":  { "N": "20480" },
  ":exp": { "N": "1719792000" }
}

Nota :sz e :exp vengono inviati come stringhe N: il tipo di numero di DynamoDB è wire- codificato come una stringa. La mappa dei valori è anche il luogo in cui riutilizzi un valore clausole: definire :s una volta, fare riferimento ad esso sia in ConditionExpression che in a FilterExpression.

Costruendo queste due mappe a mano è dove si nascondono gli errori di battitura. Il Creatore di espressioni genera l'espressione string ed entrambe le mappe insieme, con i tag type compilati, quindi i segnaposto non può andare fuori sincronia.

Il costruttore di seguito filtra su status - una parola riservata - in modo che tu possa vederlo alias automatico su #status nella mappa ExpressionAttributeNames:

Costruisci la tua richiesta
Codice generato
new QueryCommand({
  "TableName": "AuditLog",
  "KeyConditionExpression": "#hashKey = :hashKeyValue",
  "FilterExpression": "#filter0 = :filterValue0",
  "ExpressionAttributeNames": {
    "#hashKey": "pk",
    "#filter0": "status"
  },
  "ExpressionAttributeValues": {
    ":hashKeyValue": {
      "S": "TENANT#acme"
    },
    ":filterValue0": {
      "S": "active"
    }
  }
})

Nomi per percorsi annidati e scomodi

Il segnaposto # fa molto di più che schivare le parole riservate. Utilizza la sintassi del percorso del documento punti e parentesi, quindi un attributo che contiene letteralmente un punto, ad esempio un metadato key og.title — non è indirizzabile senza un segnaposto:

ProjectionExpression       #og
ExpressionAttributeNames   { "#og": "og.title" }

Senza di esso, DynamoDB legge og.title come "il campo title all'interno della mappa og"

  • una cosa completamente diversa. Stessa storia per i nomi con spazi o cifre iniziali. Per l'annidamento, inserisci un segnaposto per ciascun segmento: #meta.#author sia con #meta che #author definito.

Nomi e valori, fianco a fianco

#name:value
Sostitutiun attributo nomeun attributo valore
MappaExpressionAttributeNamesExpressionAttributeValues
Prefisso#:
Necessario perparole riservate, punti, spazisempre — nessun valore letterale in linea
Errori sbagliatiValidationExceptionValidationException

Se un valore fosse digitato come nome, DynamoDB cercherebbe un attributo chiamato published e le tue condizioni non corrisponderebbero mai a quelle che volevi, quindi API fallisce invece rumorosamente. Questa severità è una caratteristica: non esiste una risposta silenziosamente sbagliata.

Insidie e passaggi successivi

  • Dichiarazione di un segnaposto che non utilizzi — DynamoDB rifiuta le voci non utilizzate entrambe le mappe. Costruisci le mappe dall'espressione, non davanti ad essa.
  • Riutilizzare :v dopo aver modificato l'espressione: rilascia una clausola e il suo valore può indugiare, attivando l'errore di voce non utilizzata. Il costruttore li tiene sotto controllo.
  • Supponendo che un nome sia sicuro perché ha funzionato una volta - lo sono le collisioni di parole riservate per attributo. Segnaposto in modo uniforme e smetti di indovinare.

Queste mappe vengono visualizzate in ogni percorso di scrittura, quindi si accoppiano naturalmente design a tabella singola e con conoscenza quando utilizzare Query rispetto a Scan prima di collegare un filtro.

Genera l'espressione più entrambe le mappe con il file Creatore di espressioni, quindi prova DynoTable per confrontarli con i tuoi tavoli e guarda i segnaposto si risolvono.

Aggiornato