ちばのてっく

積極的にアウトプット

Boto3でDynamoDBに、上書きを防ぎながらデータを追加してみた

昨日の記事の続き。
既存データの上書きを防ぎながら、put_itemでデータを追加してみる。

上書きを防ぐためには、ConditionExpressionattribute_not_exists(プライマリキー)を設定する。 すると、プライマリキーに重複するItemが存在する場合はput_itemが行われず、ConditionalCheckFailedExceptionを返す。

やってみた

ConditionExpression = "attribute_not_exists(target)"を設定して、プライマリキーが重複するようにput_itemで更新をかけてみる。

from flask import Flask,request
import boto3 

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello world!</p>"

@app.route("/dynamodb_scan/")
def dynamodb_scan():
    client = boto3.client("dynamodb")
    response = client.scan(
        TableName="temp"
    )
    return response

@app.route("/dynamodb_put/")
def dynamodb_put():
    client = boto3.client("dynamodb")
    response  = client.put_item(
        TableName="temp",
        Item = {
            "target": { # pk
                "S": "pineapple",
            },
            "color": {
                "S": "yellow",
            }
        }
    )
    return response

@app.route("/dynamodb_put2/")
def dynamodb_put2():
    client = boto3.client("dynamodb")
    response  = client.put_item(
        TableName="temp",
        Item = {
            "target": { # pk
                "S": "pineapple",
            },
            "color": {
                "S": "green",
            }
        }
    )
    return response

# ↓今回追加した箇所
@app.route("/dynamodb_put3/")
def dynamodb_put3():
    client = boto3.client("dynamodb")
    response  = client.put_item(
        TableName="temp",
        Item = {
            "target": { # pk
                "S": "pineapple", # 既存Item
            },
            "color": {
                "S": "blue",
            }
        },
        ConditionExpression = "attribute_not_exists(target)"
    )
    return response
# ↑今回追加した箇所

if __name__ == "__main__":
    app.run(debug=True)

ブラウザでhttp://127.0.0.1:5000/dynamodb_put3/へアクセスすると、ConditionalCheckFailedExceptionと表示された。
scanでテーブルの中身を確認してみると、期待通りpineappleのcolorが更新されていないことが確認できた。

{
  "Count": 3,
  "Items": [
    {
      "color": {
        "S": "yellow"
      },
      "target": {
        "S": "banana"
      }
    },
    {
      "color": {
        "S": "red"
      },
      "target": {
        "S": "apple"
      }
    },
    {
      "color": {
        "S": "green"
      },
      "target": {
        "S": "pineapple"
      }
    }
  ],
  "ResponseMetadata": {
    "HTTPHeaders": {
      "connection": "keep-alive",
      "content-length": "183",
      "content-type": "application/x-amz-json-1.0",
      "date": "Sat, 16 Mar 2024 12:52:47 GMT",
      "server": "Server",
      "x-amz-crc32": "3681714569",
      "x-amzn-requestid": "LIL71PUF8I73CS091U1PQD4C37VV4KQNSO5AEMVJF66Q9ASUAAJG"
    },
    "HTTPStatusCode": 200,
    "RequestId": "LIL71PUF8I73CS091U1PQD4C37VV4KQNSO5AEMVJF66Q9ASUAAJG",
    "RetryAttempts": 0
  },
  "ScannedCount": 3
}

参考

条件付き配置

比較演算子および関数リファレンス