Amazon DynamoDB PartiQLのUPDATE文ではソートキーを省略できない

2022.06.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、ゲストのNTT東日本 大瀧です。 DynamoDBのPartiQLは、SQLに似た構文でDynamoDBのデータにクエリできる便利な仕組みです。スケーラビリティとのトレードオフとしてDynamoDBのデータ操作には様々な制約があり、ぱっと見では気づきにくいUPDATE文でのキー指定の制約について、(佐藤さんが1年半前に既にブログに書いていることなのですが)改めてハマったので書き残しておきます。

ソートキー付きでDynamoDBテーブルを作成

今回は以下のようなテーブルを用意しました。 id がパーティションキー、 flag がソートキーです。

SELECT文は通るのにUPDATE文はダメ

AWS管理コンソールのDynamoDB管理画面にある、PartiQLエディタからクエリを発行してみましょう。まずはSELCT文から。PartiQLにおけるSELECT文はWHERE句の条件にパーティションキーもしくはパーティションキーとソートキーをANDで入れることでDynamoDB APIのQuery APIに相当し、WHERE句なしやキー以外の属性で条件を指定すると全件取得のScan API相当になります。たとえば、パーティションキーの id で以下のようにクエリします。

SELECT * FROM updatetest WHERE id = '48ac90be-e623-11ec-b5b3-37d2ef18d343'

クエリが通り、レコードが取得できました。

一方のUPDATE文ではパーティションキーとソートキー両方をWHERE句にANDで指定する必要があります。例えば先ほどのSELECT文とほぼ同等のクエリでは、バリデーションエラーになります。

UPDATE updatetest SET role = 'BD' WHERE id = '48ac90be-e623-11ec-b5b3-37d2ef18d343'

PartiQLのUPDATE文の更新は 単一レコードのみ 可能で複数レコードの更新ができないとのことで、レコードを特定するためにパーティションキーとソートキーの指定を要求しているわけです。アプリケーションの設計としてパーティションキーを一意にしてソートキーを自由に利用するような規約のときは、UPDATE文の発行に注意が必要です。SELECT文などであらかじめ対象レコードのソートキーの値を取得してUPDATE文を発行する対処法があるかなと思います。

また、複数レコードのUPDATEを行う場合は、複数ステートメントを許容するAPIがいくつかあるので、トランザクションの要否などで使い分けます。

ちなみに、id パーティションキーのみのグローバルセカンダリインデックス(GSI)を張ってのUPDATE文も試してみましたが、UPDATE文はGSI指定をサポートしていませんでした。

まぁそんな気はしていましたが、一応試してみるのも大事かなと。

まとめ

Amazon DynamoDB PartiQLのUPDATE文ではソートキーを省略できない様子をご紹介しました。PartiQLはプレースホルダーを仕込みやすく個人的にはもう手離せない感じなので、制約に気を付けつつ使いこなしていきたいなと思っています。