DynamoDB PutItem in Go (AWS SDK v2)
PutItem writes a whole item, creating it or replacing any existing item with the same primary key. In AWS SDK for Go v2 you call client.PutItem with a dynamodb.PutItemInput whose Item map holds every attribute as a typed value from the types package.
Code
package main
import (
"context"
"errors"
"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)
_, err = client.PutItem(ctx, &dynamodb.PutItemInput{
TableName: aws.String("Music"),
Item: map[string]types.AttributeValue{
"Artist": &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
"SongTitle": &types.AttributeValueMemberS{Value: "Cubano Chant"},
"AlbumTitle": &types.AttributeValueMemberS{Value: "Danzon"},
"Year": &types.AttributeValueMemberN{Value: "1994"},
"Awards": &types.AttributeValueMemberN{Value: "0"},
},
ConditionExpression: aws.String("attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)"),
ExpressionAttributeNames: map[string]string{
"#cond0": "Artist",
"#cond1": "SongTitle",
},
})
if err != nil {
var ccf *types.ConditionalCheckFailedException
if errors.As(err, &ccf) {
fmt.Println("A song with that key already exists — not overwritten")
return
}
log.Fatalf("put item: %v", err)
}
fmt.Println("Song written")
}To build the Item map from a plain Go struct instead, use attributevalue.MarshalMap from github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue.
Explanation
Item— must contain the table's full primary key, plus any other attributes. Numbers are strings insideAttributeValueMemberN({Value: "1994"}).- Put replaces — without a condition,
PutItemsilently overwrites an existing item with the same key. UseUpdateItemto change a few attributes without clobbering the rest. ConditionExpression—attribute_not_exists(...)on the key attributes makes the write a create-only insert; the write fails withConditionalCheckFailedExceptionif the item already exists. This is DynamoDB's optimistic-locking primitive. The#cond0/#cond1aliases resolve toArtist/SongTitleviaExpressionAttributeNames(reserved-word-safe).errors.As— the Go SDK wraps service errors, so match the typed*types.ConditionalCheckFailedExceptionwitherrors.As, never by string comparison.- To get the overwritten item back, set
ReturnValues: types.ReturnValueAllOld.
Do it visually
Writing a conditional put by hand? The DynamoDB Expression Builder assembles the ConditionExpression and copies the code.
To add and edit items in a GUI — a form per attribute, type pickers, and copy-as-code — download DynoTable.
Related examples
- DynamoDB PutItem in Java — the same conditional write with AWS SDK for Java 2.x.
- DynamoDB UpdateItem in Go — change specific attributes instead of replacing the item.
- DynamoDB condition expressions —
attribute_not_exists, optimistic locking, and more. - DynamoDB ConditionalCheckFailedException — what the create-only condition throws when the item already exists.
- DynamoDB ValidationException — the catch-all for a malformed item or expression.
References
- PutItem — Amazon DynamoDB API Reference
- Use PutItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- dynamodb package — AWS SDK for Go v2 (pkg.go.dev)
- dynamodb/types package — AWS SDK for Go v2 (pkg.go.dev)
- Handling errors — AWS SDK for Go v2 Developer Guide
- Condition expressions — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.