DynamoDB Query in Go (AWS SDK v2)

Query reads every item that shares one partition key, optionally narrowing by the sort key. In AWS SDK for Go v2 you write a KeyConditionExpression on a dynamodb.QueryInput, and the built-in QueryPaginator follows LastEvaluatedKey across every result page for you.

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))
}

Explanation

  • KeyConditionExpression — must include an equality on the partition key (#hashKey = :hashKeyValue) plus at most one sort-key condition (=, <, <=, >, >=, BETWEEN, or begins_with). The #hashKey/#rangeKey aliases resolve to Artist/SongTitle via ExpressionAttributeNames (reserved-word-safe).
  • ExpressionAttributeValues — the :placeholder → typed-value map (&types.AttributeValueMemberS{...}).
  • Pagination — one Query returns at most 1 MB. dynamodb.NewQueryPaginator wraps the client and keeps calling until LastEvaluatedKey is exhausted; the HasMorePages() / NextPage(ctx) loop is the SDK's canonical pattern.
  • Set ScanIndexForward: aws.Bool(false) to reverse the sort-key order (ascending is the default).
  • Query a secondary index by adding IndexName: aws.String("...").
  • Prefer building conditions in code? The expression package (github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression) composes expression.Key(...).Equal(...) builders and generates the name/value maps; attributevalue.UnmarshalListOfMaps turns page.Items into Go structs.

Do it visually

The DynamoDB Expression Builder assembles the key condition and copies runnable code, so you don't hand-write placeholder and value maps.

To run queries against real tables in a GUI — key-condition form, paginated grid, copy-as-code — download DynoTable.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Build this request visually

Compose this operation in the free DynamoDB Query Builder — key condition, filter, index, Limit, sort order, and a pagination loop — and copy it back as a runnable SDK v3, CLI, or boto3 program.

Open the DynamoDB Query Builder

Work with DynamoDB without the Console

DynoTable is a fast desktop client for DynamoDB — browse tables, run SQL-style queries, and edit items locally.