LoginSignup
2
0

More than 1 year has passed since last update.

Goを使ってDynamoDBに一括書き込み

Posted at

aws-sdk-goを使ってDynamoDBを操作するメモです。
こちらのリンクを見ながら基本的なCRUDは一通りできたのですが、一括処理はうまくできませんでした。
一括書き込みの箇所についてデモを作成しようと思います。

環境

go version 1.17.2

aws-sdk-go v1.44.180

前提

DynamoDBにユーザ情報を一括登録する想定です。
ユーザ情報はHTTPリクエストボディから受け取ります。
Lambda上で受け取ったデータを構造体に変換し、DynamoDBに書き込みます。

構造体を定義

ユーザ情報を表現する構造体を定義します。

main.go
type User struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

リクエストボディからのデータを構造体に変換

APIGatewayからリクエストボディを受け取り、User構造体に変換します。

main.go
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
  body := request.Body
  err = json.Unmarshal([]byte(body), &users)
	if err != nil {
		return events.APIGatewayProxyResponse{
			Body: err.Error(),
			StatusCode: 501,
		}, err
	}
  ...
}

DynamoDBに一括書き込み

BatchWriteItemというメソッドを使います。
このメソッド注意点があり、一回で登録できるデータは25個までです。
今回はUserの配列を書き込みたいので、25個登録したら次に要素にアクセスするというfor文を回します。

main.go
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
  ...
  batchSize := 25
	start := 0
	end := start + batchSize
	for start < len(users) {
		var writeReqs []*dynamodb.WriteRequest
		if end > len(users) {
			end = len(users)
		}

		for _, user := range users[start:end] {
			item, err := dynamodbattribute.MarshalMap(user)
			if err != nil {
				return events.APIGatewayProxyResponse{
					Body:       err.Error(),
					StatusCode: 501,
				}, err
			}

			writeReqs = append(
				writeReqs,
				&dynamodb.WriteRequest{
					PutRequest: &dynamodb.PutRequest{
						Item: item,
					},
				},
			)
		}

		_, err = db.BatchWriteItem(&dynamodb.BatchWriteItemInput{
			RequestItems: map[string][]*dynamodb.WriteRequest{"TABLE_NAME": writeReqs},
		})
		if err != nil {
			return events.APIGatewayProxyResponse{
				Body:       err.Error(),
				StatusCode: 501,
			}, err
		}

		start = end
		end += batchSize
	}
  ...
}

レスポンス実装

登録したデータをHTTPレスポンスとして返します。
ユーザの配列を[]byte -> stringと変換します。

main.go
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
  ...
  bytes, err := json.Marshal(users)
	if err != nil {
		return events.APIGatewayProxyResponse{
			Body:       err.Error(),
			StatusCode: 501,
		}, err
	}

	return events.APIGatewayProxyResponse{
		Body:       string(bytes),
		StatusCode: 200,
	}, nil
}

以上です。

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0