DynamoDB Query in Go (AWS SDK v2)

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 AWS SDK for Go v2 hinzufügt, ist QueryPaginator: Er macht aus der LastEvaluatedKey-Schleife eine for-Schleife — und nimmt dir dabei klammheimlich die Möglichkeit, anzuhalten.

Code

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

func main() {
	ctx := context.TODO()
	cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
	if err != nil {
		log.Fatalf("load config: %v", err)
	}
	client := dynamodb.NewFromConfig(cfg)

	paginator := dynamodb.NewQueryPaginator(client, &dynamodb.QueryInput{
		TableName: aws.String("Music"),
		KeyConditionExpression: aws.String(
			"#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)"),
		ExpressionAttributeNames: map[string]string{
			"#hashKey":  "Artist",
			"#rangeKey": "SongTitle",
		},
		ExpressionAttributeValues: map[string]types.AttributeValue{
			":hashKeyValue":  &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
			":rangeKeyValue": &types.AttributeValueMemberS{Value: "C"},
		},
	})

	var items []map[string]types.AttributeValue
	for paginator.HasMorePages() {
		page, err := paginator.NextPage(ctx)
		if err != nil {
			log.Fatalf("query: %v", err)
		}
		items = append(items, page.Items...)
	}
	fmt.Printf("Found %d items\n", len(items))
}

Erklärung

Limit begrenzt nicht, was der Paginator liest. Das ist der Punkt, der Geld kostet. Limit: aws.Int32(5) am obigen Input gesetzt und über eine Partition aus 30 Items zu je ~60 KB ausgeführt, ergab:

page 1: Count=5 CU=37.0   page 5: Count=5 CU=37.0
page 2: Count=5 CU=37.0   page 6: Count=5 CU=37.0
page 3: Count=5 CU=37.0   page 7: Count=0 CU=0.0
page 4: Count=5 CU=37.0   total: 30 items, 222.0 units

Alle dreißig Items kamen zurück. Limit ist eine Seitengröße, und die Aufgabe des Paginators ist es, weiterzufragen, bis die Seiten ausgehen — beides hebt sich also exakt auf. AWS definiert es als "the maximum number of items to evaluate (not necessarily the number of matching items)" (abgerufen am 2026-07-28). Wenn du die ersten fünf Items willst, brich die Schleife nach der ersten Seite selbst mit break ab.

Kleine Seiten kosten etwas mehr, nicht weniger. Dieselbe Partition ohne Limit gelesen paginiert in zwei Seiten für 220,0 Einheiten; mit Limit: 5 brauchte es sieben Aufrufe für 222,0. Jede Seite rundet ihre eigene Byte-Summe auf die nächste 4-KB-Grenze auf — mehr Seiten heißt also mehr Rundung, plus sechs zusätzliche Round-Trips an Latenz. Limit zu senken, um „weniger zu lesen", bringt dir keines von beidem.

Die Schleife macht immer einen Aufruf mehr, als es Daten gibt. Seite 7 oben lieferte null Items. DynamoDB gibt einen LastEvaluatedKey zurück, sobald Limit erreicht wurde — egal ob noch etwas folgt — und HasMorePages() glaubt ihm. Ein Limit-behafteter Paginator endet also mit einer vergeudeten Anfrage, und jeder Seiteneffekt pro Seite (ein Fortschrittsbalken, ein Batch-Flush, eine Log-Zeile) feuert einmal gegen eine leere Seite. Sichere das über len(page.Items) ab.

HasMorePages() ist vor der ersten Anfrage true. Es wird auf true initialisiert, damit die for-Schleife überhaupt startet — es ist also eine Schleifenbedingung und kein „gibt es Daten"-Check. Wer es aufruft, um zu entscheiden, ob sich eine Abfrage lohnt, bekommt immer ein Ja.

Fehler tauchen pro Seite auf, und ein Teil-Read ist ein realer Zustand. NextPage liefert denselben verpackten Smithy-Fehler wie jeder andere Aufruf — packe ihn also mit errors.As gegen *types.ProvisionedThroughputExceededException und Verwandte aus, statt Strings zu vergleichen. Das log.Fatalf im Snippet wirft die bereits gesammelten Seiten weg; in einem Service willst du normalerweise items behalten und melden, wie weit du gekommen bist.

ScanIndexForward ist der einzige Weg, eine Partition rückwärts zu lesen. Setze ScanIndexForward: aws.Bool(false) für absteigende Sort-Key-Reihenfolge. Ein „Sortieren nach" für irgendetwas anderes gibt es nicht: Die Reihenfolge kommt vom Sort Key, und brauchst du eine andere Reihenfolge, brauchst du einen anderen Index. IndexName: aws.String("...") verschiebt die gesamte Abfrage auf diesen Index.

Zwei Pakete machen das kürzer. github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression baut die Key Condition und beide Platzhalter-Maps aus expression.Key("Artist").Equal(expression.Value("Arturo Sandoval")) — das räumt die handgeschriebenen #hashKey/:hashKeyValue-Paare weg und mit ihnen das Risiko reservierter Wörter. attributevalue.UnmarshalListOfMaps(page.Items, &songs) macht aus einer Seite direkt ein []Song.

Mach es visuell

Die beiden Platzhalter-Maps sind der Teil, den man besser generieren als tippen lässt. Der kostenlose DynamoDB Expression Builder setzt die Key Condition mit passenden ExpressionAttributeNames und ExpressionAttributeValues zusammen und gibt das Go-Literal aus, sodass Namen und Werte nicht auseinanderdriften können.

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

Verwandte Beispiele

Referenzen

Am 2026-07-28 auf go1.26.5 mit aws-sdk-go-v2/service/dynamodb v1.62.1 gegen DynamoDB Local (amazon/dynamodb-local) auf Port 9000 gemessen, über eine Partition aus 30 Items zu je ~60 KB. Die Zählungen und Kapazitätswerte pro Seite sind mitgeschnittene Ausgabe. DynamoDB Local wendet die dokumentierten Rundungsregeln an; behandle die absoluten Einheiten als Demonstration der Größenordnung und miss 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.