【アップデート】DynamoDBの文字列型/バイナリ型項目に空文字列が登録できるようになりました!!

地味にうれしいアップデートです
2020.05.19

CX事業本部@大阪の岩田です。2020/5/18付けのアップデートにより、DynamoDBの文字列型/バイナリ型項目に空文字列が登録できるようになりました。

簡単ですが、このアップデートについてご紹介します。

何が変わったの?

これまでDynamoDBでは文字列型およびバイナリ型の項目に空文字列を登録することができませんでした。

例えばBoto3を使って以下のようなデータを登録しようとすると、、、

{
  "id":1 ,
  "attr1": ""
}

以下のようなエラーが発生して登録することができませんでした。

One or more parameter values were invalid: An AttributeValue may not contain an empty string

そのため、アプリケーションから空文字列を扱いたい場合は一旦空文字列をNULLに変換してからDynamoDBのテーブルに登録し、読み出し時に再度NULLから空文字列に変換するといった処理が必要でした。この方法だとアプリケーションからは空文字列とNULLを区別して扱うことができませんし、空文字列の変換忘れにより登録が失敗するというバグを生み出しがちでした。しかし、今回のアップデートにより先程の例のような空文字列の項目であってもそのまま登録することが可能になりました。アプリケーション側からは、面倒な変換処理なしで空文字列をそのまま扱うことが可能になりました。

注意事項

パーティションキー、及びソートキー(LSIのソートキー含む)として指定された項目には空文字列を登録することはできません。また、GSIのキーとして登録された項目に空文字列を登録した場合、インデックスは作成されません。この辺りはNULLを登録した場合と同じなので、いわゆるスパースインデックスをイメージして頂ければ分かりやすいと思います。また空文字列が登録された項目に後からGSIを設定することは可能ですが、既にGSIのキーとして設定済みの項目には空文字列を登録することはできません。

やってみる

実際にマネコンから空文字列のデータを登録してみます。

非キー項目に空文字列を登録してみる

idというパーティションキーを持つテーブルの文字列型の項目attr1に空文字列を登録してみます。

登録後のマネコンの表示です。

attr1は「empty」と表示されてます。

同様にバイナリ型でも試してみましょう。バイナリ型のbinattr1という項目に空文字列を登録してみます。

こちらもマネコンの表示を確認してみます。

binattr1は「empty」と表示されてます。

AWS CLIからの表示も確認しておきましょう。

$ aws dynamodb scan --table-name test
{
    "Items": [
        {
            "id": {
                "N": "2"
            },
            "binattr1": {
                "B": ""
            }
        },
        {
            "id": {
                "N": "1"
            },
            "attr1": {
                "S": ""
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 2,
    "ConsumedCapacity": null
}

レスポンスとして空文字列が返却されていることが分かります。

キー項目/インデックスとして指定された項目に空文字列の登録を試みる

注意事項についても確認しておきましょう。str-idという文字列型の項目をパーティションキーとして指定したテーブルに対して、str-idに空文字列を指定したデータの登録を試みます。

One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: str-id (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: xxxxxx)

というエラーがでて登録に失敗しました。

空文字列が登録された項目にGSIを設定してみる

続いて、先程attr1に空文字列を登録したテーブルにattr1をパーティションキーとしたGSIを追加してみます。GSIの作成完了後にGSIをスキャンしてみると、、、

インデックスが作成されていないことが分かります。

GSIとして指定された項目に空文字列を登録してみる

attr1にGSIを設定したので、新しくattr1に空文字列を指定したアイテムの登録を試みます。

今度は

One or more parameter values are not valid. A value specified for a secondary index key is not supported.
The AttributeValue for a key attribute cannot contain an empty string value.
IndexName: attr1-index, IndexKey: attr1 (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: xxx)

というエラーになりました

LSIとして指定された項目に空文字列を登録してみる

最後にLSIの動作を確認しておきましょう。以下定義でテーブルを作成します。

  • プライマリキー
    • パーティションキー: str-pkey
    • ソートキー: str-skey
  • LSI
    • パーティションキー: str-pkey
    • パーティションキー: attr1

このテーブルに対して、LSIのソートキーattr1を空文字列に設定したデータの登録を試みると、、、

One or more parameter values are not valid. A value specified for a secondary index key is not supported. The AttributeValue for a key attribute cannot contain an empty string value. IndexName: str-pkey-attr1-index, IndexKey: attr1 (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: xxxxxx)

というエラーで登録できませんでした。想定通りの挙動です。

まとめ

地味なアップデートですが、開発者からすると結構うれしいアップデートなのではないでしょうか?これでまた1つDynamoDBが使いやすくなりました。