boto3経由でDynamodbにPartiQLを実行

# boto3経由でDynamodbにPartiQLを実行
## はじめに
昨年11月にDynamoDBにSQL互換のクエリ言語**PartiQL**が実行できるようになりました。
https://aws.amazon.com/jp/about-aws/whats-new/2020/11/you-now-can-use-a-sql-compatible-query-language-to-query-insert-update-and-delete-table-data-in-amazon-dynamodb/

私はcliではなく、boto3で実行する際のメモです。

## 環境

|項目|version|
|---|---|
|Python|3.8.5|
|boto3|1.16.51|
|botocore|1.19.51|

## 実行

boto3経由でCREATE TABLE時のIndexの仕方がよくわからないのでとりあえず、CREATE TABLEだけを実行するとUnsupportedがでました。


```python
import boto3

clinet = boto3.client('dynamodb')
clinet = clinet.execute_statement(Statement='CREATE TABLE Questions')
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the ExecuteStatement operation: Unsupported operation: CreateTable
```

なのでAWSコンソールでテーブルを作成します。
![Screenshot from 2021-01-09 12-09-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235240/feb66c8b-1478-0fab-9109-9c70427b4c54.png)


とりあえずデータをINSERTしてみます。

```python
>>> import boto3

>>> clinet = boto3.client('dynamodb')
>>> clinet.execute_statement(Statement="INSERT INTO Questions VALUE {'questionId': 'hogehoge', 'title':'fugafuga'}")
{'Items': [], 'ResponseMetadata': {'RequestId': 'STSLJF4VO9CA61MU1SKCOVLGMRVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:13:13 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '12', 'connection': 'keep-alive', 'x-amzn-requestid': 'STSLJF4VO9CA61MU1SKCOVLGMRVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2770214093'}, 'RetryAttempts': 0}}

```
コンソールを確認するとデータが作成されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235240/22d0575e-47df-81c1-2a41-44f7d6fca9ec.png)

boto3経由でも確認できます。

```python
>>> clinet.execute_statement(Statement="SELECT * FROM Questions")
{'Items': [{'questionId': {'S': 'hogehoge'}, 'title': {'S': 'fugafuga'}}], 'ResponseMetadata': {'RequestId': 'I6S1NDUU93R9O4SE8T9657AH77VV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:15:12 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '68', 'connection': 'keep-alive', 'x-amzn-requestid': 'I6S1NDUU93R9O4SE8T9657AH77VV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2555902000'}, 'RetryAttempts': 0}}

```

UPDATEして確認してみます。

```python
>>> clinet.execute_statement(Statement="UPDATE Questions SET title='foofoo' WHERE questionId='hogehoge'")
{'Items': [], 'ResponseMetadata': {'RequestId': 'C5TMDKMTT9NM2RPTVVK0GBOTKFVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:18:58 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '12', 'connection': 'keep-alive', 'x-amzn-requestid': 'C5TMDKMTT9NM2RPTVVK0GBOTKFVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2770214093'}, 'RetryAttempts': 0}}
>>> clinet.execute_statement(Statement="SELECT * FROM Questions")
{'Items': [{'questionId': {'S': 'hogehoge'}, 'title': {'S': 'foofoo'}}], 'ResponseMetadata': {'RequestId': '898QE0R431PLKG3QJRGH26EUN7VV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:19:15 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '66', 'connection': 'keep-alive', 'x-amzn-requestid': '898QE0R431PLKG3QJRGH26EUN7VV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '379791711'}, 'RetryAttempts': 0}}

```

更新できました。
ただしKeyを指定せずにUPDATEするとエラーになります。

```python
>>> clinet.execute_statement(Statement="UPDATE Questions SET title='foofoo'")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/kohei/.local/lib/python3.8/site-packages/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/kohei/.local/lib/python3.8/site-packages/botocore/client.py", line 676, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the ExecuteStatement operation: Where clause does not contain a mandatory equality on all key attributes

```

DELETEもできました。

```python
>>> clinet.execute_statement(Statement="DELETE FROM Questions WHERE questionId='hogehoge'")
{'Items': [], 'ResponseMetadata': {'RequestId': 'AQOONAN30T0NHC0OAPS1QLFH3RVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:21:54 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '12', 'connection': 'keep-alive', 'x-amzn-requestid': 'AQOONAN30T0NHC0OAPS1QLFH3RVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2770214093'}, 'RetryAttempts': 0}}
>>> clinet.execute_statement(Statement="SELECT * FROM Questions")
{'Items': [], 'ResponseMetadata': {'RequestId': 'AV8FBJ2FU4KUDEI3J0R184RJ47VV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 09 Jan 2021 08:21:57 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '12', 'connection': 'keep-alive', 'x-amzn-requestid': 'AV8FBJ2FU4KUDEI3J0R184RJ47VV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2770214093'}, 'RetryAttempts': 0}}

```

## まとめ
Indexを意識せずQueryを実行することができてしまうので少し不安ですが、これまでのSQLインターフェースが用意されているのはいいですね。

## 参考
[boto3ドキュメント](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html?highlight=execute_statement#DynamoDB.Client.execute_statement
)