AWS DynamoDBでエラー[Invalid KeyConditionExpression: Syntax error; token: -, near]が発生する
何をしようとしたのか
Node.jsのAWS SDKを使用して、query( )を行いたかった。 (DocumentClientクラスを使用) 以下のようなparamを設定したところタイトルの通りのエラーが発生した。
エラー本文はプロダクトに関する情報があるため詳細なスタックトレースは割愛する。
エラー本文
{ ValidationException: Invalid KeyConditionExpression: Syntax error; token: "-", near: ":1212_***-test"
at Request.extractError......
stackTrace.....
message:
'Invalid KeyConditionExpression: Syntax error; token: "-", near: ":1212_***-test"',
code: 'ValidationException',
time: 2019-10-07T23:08:32.414Z,
requestId: '4D8198PHE**************************************',
statusCode: 400,
retryable: false,
retryDelay: 41.67230422166851 }
メソッドに渡すパラメータ
const TABLE_NAME = 'sample_table; let hash_key = "1212_***-test-sample"; let params = { TableName: TABLE_NAME, KeyConditionExpression:`sample_group =:${hash_key}` };
結局原因は?
以下のissueにあるようにkeyにダッシュは使えないらしい。
対策した
以下のようにコードを変更して試してみた。
let params = { TableName: TABLE_NAME, ExpressionAttributeValues:{ ":hash": "1212_***-test-sample", ":range": "test_id" }, KeyConditionExpression:"sample_group = :hash AND sample_id = :range" };
つまりどういうことなのか?
KeyConditionExpression には予約済みの用語や、先程のダッシュのように禁止されている記号は入力できない。
その場合、コードのようにExpressionAttributeValuesで別名を定義して代入する必要がある。
上記の例ではhash_keyが:hashに、range_keyが:rangeに別名が付けられたということになっている。
なお今の例では、クエリに渡す「値」を別名で置き換えたが、テーブルの「カラム名」自体が予約語に引っかかる場合もある。
その場合はExpressionAttributeNameで同じ要領で別名を定義してやると良い。
個人的には値にどんな値が入るか不明確なときにはExpressionAttributeValueを定義しておくほうが安全だと思う。