DynamoDB Query mit der AWS CLI

aws dynamodb query liest eine Partition, optional über den Sort Key eingegrenzt (Query vs. Scan behandelt, wann das die richtige Wahl ist, und Key Condition Expressions listet jeden zulässigen Operator). Was die CLI obendrauf legt, ist eine eigene Paginierungsschicht — und die ist die Quelle der meisten Überraschungen bei diesem Befehl.

Code

aws dynamodb query \
  --table-name 'Music' \
  --key-condition-expression '#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)' \
  --expression-attribute-names '{"#hashKey":"Artist","#rangeKey":"SongTitle"}' \
  --expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"},":rangeKeyValue":{"S":"C"}}'

Die Aliase #hashKey/#rangeKey lösen über --expression-attribute-names zu Artist/SongTitle auf — genau das verhindert, dass ein reserviertes Wort den Befehl zerlegt. Füge --no-scan-index-forward für absteigende Sort-Key-Reihenfolge hinzu; aufsteigend ist der Standard.

Paginierung

Standardmäßig paginiert die CLI automatisch — sie folgt LastEvaluatedKey intern und gibt das zusammengeführte Ergebnis aus. Um manuell zu paginieren (z. B. bei großen Ergebnismengen), steuerst du das so:

aws dynamodb query \
  --table-name 'Music' \
  --key-condition-expression '#hashKey = :hashKeyValue' \
  --expression-attribute-names '{"#hashKey":"Artist"}' \
  --expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"}}' \
  --page-size 100 \
  --max-items 50
# The output includes a "NextToken"; pass it back with --starting-token to continue.

Erklärung

Die CLI versteckt die Paginierung — auch vor der Kostenangabe. Eine Partition mit 30 Items zu je ~60 KB befüllt, also rund 1,8 MB und damit zwei Service-Seiten, dann dieselbe Abfrage dreimal mit --return-consumed-capacity TOTAL ausgeführt:

default (auto-paginate)  Count: 30   CapacityUnits: 132.0   LastEvaluatedKey: null
--no-paginate            Count: 18   CapacityUnits: 132.0   LastEvaluatedKey: {…S017}
--max-items 3            Count: 18   items printed: 3       NextToken: eyJFeGNsdXNpdmVTdGFydEtleSI6…

Von Hand zu paginieren zeigte die wahren Kosten: Seite 1 waren 18 Items zu 132,0 Einheiten, Seite 2 waren 12 Items zu 88,0 — die Abfrage verbrauchte also tatsächlich 220,0 Read-Einheiten. Der auto-paginierte Lauf machte beide Aufrufe, lieferte alle 30 Items und meldete 132,0. Die CLI führt Items und Count über Seiten hinweg zusammen, ConsumedCapacity aber nicht — die ausgegebene Zahl untertreibt diese Abfrage also um 40 %. Wenn du Kapazität anhand der CLI-Ausgabe dimensionierst, paginiere von Hand, sonst dimensionierst du für eine Seite.

--max-items ist ein Ausgabelimit. Es ist kein Limit. Der dritte Lauf oben gab drei Items aus und meldete trotzdem Count: 18 und ScannedCount: 18, weil die Service-Seite, die er abgeschnitten hat, 18 Items und rund 1 MB groß war. Bezahlt hast du alles davon. Der DynamoDB-Parameter, der den Read wirklich begrenzt, heißt Limit, und die CLI legt ihn als --page-size offen.

Die beiden Flags erledigen also völlig unterschiedliche Aufgaben. --page-size wird zum Limit der API und ändert, was jeder Service-Aufruf liest; --max-items entscheidet nur, wie viel vom zusammengeführten Ergebnis in deinem Terminal ankommt, und gibt für den Rest ein NextToken aus. Dieses Token ist ein Base64-Blob aus der Buchführung der CLI selbst, nicht DynamoDBs LastEvaluatedKey, und es geht über --starting-token wieder hinein.

Es gibt kein --limit und kein --exclusive-start-key. Sieh dir aws dynamodb query help auf 2.36.9 an: Keines von beiden taucht in der Synopsis auf. Die CLI entfernt beide Paginierungsparameter von DynamoDB und setzt ihre eigenen drei an ihre Stelle. Die naheliegende Schleife — LastEvaluatedKey aus einem Aufruf nehmen und in den nächsten geben — hat also kein Flag, in das sie ihn geben könnte. Der Weg zurück zur rohen API ist --cli-input-json, das die Anfrage wortgetreu übernimmt:

--cli-input-json with "Limit": 5 and an "ExclusiveStartKey"
  → Count: 5   CapacityUnits: 37.0   LastEvaluatedKey: {"Artist":…,"SongTitle":"S007"}

Beachte, dass das auch den Paginator abschaltete: Der Lauf lieferte eine Seite und einen echten LastEvaluatedKey, sogar ohne --no-paginate. Wenn du eine Shell-Schleife über eine große Partition schreibst, ist --cli-input-json die ehrliche Form und --no-paginate die schnelle.

--query läuft, nachdem das Geld ausgegeben ist. Das globale --query-Flag ist JMESPath, angewendet auf die Antwort in deiner Shell. Ein JMESPath-Ausdruck wie Items[?Year > '2010'] sieht aus wie ein Filter und ist keiner: Jedes Item wurde gelesen, übertragen und abgerechnet, bevor JMESPath es überhaupt gesehen hat. --filter-expression verhindert immerhin die Übertragung der Daten, aber AWS ist eindeutig, dass er "is applied after the items have already been read; the process of filtering does not consume any additional read capacity units" (abgerufen am 2026-07-28). Das schneidet in beide Richtungen, denn es heißt auch, dass der Filter sie nicht verringert. Weniger lesen geht nur über eine engere Key Condition oder einen Index.

Eine Seite ist 1 MB, egal worum du gebeten hast. "A single Query operation will read up to the maximum number of items set (if using the Limit parameter) or a maximum of 1 MB of data" (abgerufen am 2026-07-28). Eine breitere Partition paginiert immer — deshalb war die 30-Item-Abfrage oben nie ein einzelner Aufruf.

Einen Index abzufragen kostet ein Flag mehr. --index-name schaltet die Key Condition auf die Schlüssel dieses Index um; ein Global Secondary Index lehnt zudem --consistent-read ab. Siehe Einen GSI mit der AWS CLI abfragen.

Mach es visuell

Die Key Condition, die zwei Platzhalter-Maps und die Paginierungsschleife in einem Befehl richtig hinzubekommen, ist hier die ganze Schwierigkeit. Der kostenlose DynamoDB Query Builder setzt die Anfrage zusammen — inklusive Index und Paginierung — und gibt sie als lauffähigen CLI-Befehl aus.

Um Abfragen gegen deine eigenen Tabellen auszuführen — Key-Condition-Formular, ein Grid, das beim Scrollen nachlädt, die Anfrage als CLI-Befehl wieder herauskopieren — lade DynoTable herunter.

Verwandte Leitfäden

Referenzen

Am 2026-07-28 mit aws-cli/2.36.9 gegen DynamoDB Local (amazon/dynamodb-local) auf Port 9000 gemessen, über eine Partition aus 30 Items zu je ~60 KB. Die Counts, Tokens und Kapazitätswerte oben sind mitgeschnittene Ausgabe. DynamoDB Local berechnet Kapazität nach den dokumentierten Rundungsregeln; behandle die absoluten Zahlen als Demonstration der Größenordnung und miss deine eigenen Tabellen gegen den Dienst, bevor du dimensionierst.

Diesen Request visuell bauen

Stelle diese Operation im kostenlosen DynamoDB Query Builder zusammen — Key-Bedingung, Filter, Index, Limit, Sortierreihenfolge und eine Paginierungsschleife — und kopiere sie als lauffähiges SDK-v3-, CLI- oder boto3-Programm zurück.

DynamoDB Query Builder öffnen

Mit DynamoDB ohne die Console arbeiten

Ein schneller DynamoDB-Desktop-Client, der das echte SQL ausführt, das DynamoDB nicht kann — JOINs, GROUP BY, Aggregationen — mit visueller Bearbeitung und einem KI-Agenten auf deinen eigenen Bedrock-Schlüsseln.

30 Tage kostenlos testen, keine Kreditkarte — danach der Kostenlos-Tarif ohne Zeitlimit.