

# DynamoDB 用の PartiQL の開始方法
<a name="ql-gettingstarted"></a>

このセクションでは、Amazon DynamoDB コンソール、AWS Command Line Interface (AWS CLI)、および DynamoDB API から DynamoDB 用の PartiQL を使用する方法について説明します。

次の例では、「[DynamoDB の開始方法](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)」チュートリアルで、DynamoDB テーブルを定義していることが前提です。

DynamoDB コンソール、AWS Command Line Interface、または DynamoDB API を使用して DynamoDB にアクセスする方法については、「[DynamoDB へのアクセス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)」を参照してください。

[NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) を[ダウンロード](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html)して、[DynamoDB 用の PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) ステートメントを構築するには、DynamoDB [Operation Builder](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html) 用の NoSQL Workbench の右上にある **[PartiQL operations]** (PartiQL オペレーション) を選択します。

------
#### [ Console ]

![\[Music テーブルに対してクエリオペレーションを実行した結果を示す PartiQL エディタインターフェイス。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. AWS マネジメントコンソール にサインインして DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. コンソール左側のナビゲーションペインで、[**PartiQL エディター**] を選択します。

1. [**Music**] テーブルを選択します。

1. **[Query table]** (クエリテーブル) を選択します。このアクションで生成したクエリは、完全なテーブルスキャンを実行しません。

1. `partitionKeyValue` を文字列型の値である `Acme Band` に置換します。`sortKeyValue` を文字列型の値である `Happy Day` に置換します。

1. [**実行**] ボタンを選択します。

1. **[Table view]** (テーブルビュー) または **[JSON view]** (JSON ビュー) ボタンを選択すると、クエリの結果を確認できます。

------
#### [ NoSQL workbench ]

![\[NoSQL Workbench インターフェイス。Music テーブルに対して実行できる PartiQL SELECT ステートメントを示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. [**PartiQL ステートメント**] を選択します。

1. 次の PartiQL [[SELECT statement]](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) (SELECT ステートメント) を入力します。

   ```
   SELECT *                                         
   FROM Music  
   WHERE Artist=? and SongTitle=?
   ```

1. `Artist` および `SongTitle` パラメータの値を指定するには

   1. [**オプションのリクエストパラメータ**] を選択します。

   1. [**新しいパラメータの追加**] を選択します。

   1. 属性タイプとして **[string]** (文字列型) を選択し、値に `Acme Band` を選択します。

   1. ステップ b とステップ c を繰り返し、**[string]** (文字列型) のタイプと `PartiQL Rocks` の値を選択します。

1. コードを生成する場合は、[**Generate code (コードの生成)**] を選択します。

   表示されたタブから目的の言語を選択します。これで、このコードをコピーしてアプリケーションで使用できるようになります。

1. オペレーションをすぐに実行する場合は、[**実行**] をクリックします。

------
#### [ AWS CLI ]

1. INSERT PartiQL ステートメントを使用して、`Music` テーブルに項目を作成します。

   ```
   aws dynamodb execute-statement --statement "INSERT INTO Music  \
   					    VALUE  \
   					    {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"
   ```

1. SELECT PartiQL ステートメントを使用して、Music テーブルから項目を取得します。

   ```
   aws dynamodb execute-statement --statement "SELECT * FROM Music   \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. UPDATE PartiQL ステートメントを使用して、`Music` テーブルの項目を更新します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardsWon=1  \
                                               SET AwardDetail={'Grammys':[2020, 2018]}  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目のリスト値を追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルから項目のリスト値を削除します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               REMOVE AwardDetail.Grammys[2]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目の新しいマップメンバーを追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.BillBoard=[2020]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目の新しい文字列セットの属性を追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =<<'member1', 'member2'>>  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルで、項目の文字列セットの属性を更新します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =set_add(BandMembers, <<'newmember'>>)  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. DELETE PartiQL ステートメントを使用して、`Music` テーブルから項目を削除します。

   ```
   aws dynamodb execute-statement --statement "DELETE  FROM Music  \
       WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

------
#### [ Java ]

```
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.model.AttributeValue;
import software.amazon.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.dynamodb.model.ExecuteStatementRequest;
import software.amazon.dynamodb.model.ExecuteStatementResult;
import software.amazon.dynamodb.model.InternalServerErrorException;
import software.amazon.dynamodb.model.ItemCollectionSizeLimitExceededException;
import software.amazon.dynamodb.model.ProvisionedThroughputExceededException;
import software.amazon.dynamodb.model.RequestLimitExceededException;
import software.amazon.dynamodb.model.ResourceNotFoundException;
import software.amazon.dynamodb.model.TransactionConflictException;

public class DynamoDBPartiQGettingStarted {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-1");

        try {
            // Create ExecuteStatementRequest
            ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
            List<AttributeValue> parameters= getPartiQLParameters();

            //Create an item in the Music table using the INSERT PartiQL statement
            processResults(executeStatementRequest(dynamoDB, "INSERT INTO Music value {'Artist':?,'SongTitle':?}", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //Update an item in the Music table using the UPDATE PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist=? and SongTitle=?", parameters));

            //Add a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  where Artist=? and SongTitle=?", parameters));

            //Remove a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music REMOVE AwardDetail.Grammys[2]   where Artist=? and SongTitle=?", parameters));

            //Add a new map member for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music set AwardDetail.BillBoard=[2020] where Artist=? and SongTitle=?", parameters));

            //Add a new string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =<<'member1', 'member2'>> where Artist=? and SongTitle=?", parameters));

            //update a string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =set_add(BandMembers, <<'newmember'>>) where Artist=? and SongTitle=?", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //delete an item from the Music Table
            processResults(executeStatementRequest(dynamoDB, "DELETE  FROM Music  where Artist=? and SongTitle=?", parameters));
        } catch (Exception e) {
            handleExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static List<AttributeValue> getPartiQLParameters() {
        List<AttributeValue> parameters = new ArrayList<AttributeValue>();
        parameters.add(new AttributeValue("Acme Band"));
        parameters.add(new AttributeValue("PartiQL Rocks"));
        return parameters;
    }

    private static ExecuteStatementResult executeStatementRequest(AmazonDynamoDB client, String statement, List<AttributeValue> parameters ) {
        ExecuteStatementRequest request = new ExecuteStatementRequest();
        request.setStatement(statement);
        request.setParameters(parameters);
        return client.executeStatement(request);
    }

    private static void processResults(ExecuteStatementResult executeStatementResult) {
        System.out.println("ExecuteStatement successful: "+ executeStatementResult.toString());

    }

    // Handles errors during ExecuteStatement execution. Use recommendations in error messages below to add error handling specific to
    // your application use-case.
    private static void handleExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("Condition check specified in the operation failed, review and update the condition " +
                                       "check before retrying. Error: " + ccfe.getErrorMessage());
        } catch (TransactionConflictException tce) {
            System.out.println("Operation was rejected because there is an ongoing transaction for the item, generally " +
                                       "safe to retry with exponential back-off. Error: " + tce.getErrorMessage());
        } catch (ItemCollectionSizeLimitExceededException icslee) {
            System.out.println("An item collection is too large, you\'re using Local Secondary Index and exceeded " +
                                       "size limit of items per partition key. Consider using Global Secondary Index instead. Error: " + icslee.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " +
                                       "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                                       "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " +
                                       ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " +
                                       "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                                       "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                                       "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                                       "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

## パラメータ化されたステートメントの使用
<a name="ql-gettingstarted.parameterized"></a>

PartiQL ステートメント文字列に値を直接埋め込む代わりに、疑問符 (`?`) プレースホルダーを使用して、`Parameters` フィールドに値を個別に指定できます。各 `?` は、指定された順序で、対応するパラメータ値に置き換えられます。

パラメータ化されたステートメントを使用すると、ステートメント構造がデータ値から分離され、ステートメントの読み取りと再利用が容易になるため、ベストプラクティスです。また、ステートメント文字列の属性値を手動でフォーマットしたりエスケープしたりする必要もなくなります。

パラメータ化されたステートメントは `ExecuteStatement`、`BatchExecuteStatement`、および `ExecuteTransaction` オペレーションでサポートされています。

次の例では、パーティションキーとソートキーのパラメータ化された値を使用して、`Music` テーブルから項目を取得します。

------
#### [ AWS CLI parameterized ]

```
aws dynamodb execute-statement \
    --statement "SELECT * FROM \"Music\" WHERE Artist=? AND SongTitle=?" \
    --parameters '[{"S": "Acme Band"}, {"S": "PartiQL Rocks"}]'
```

------
#### [ Java parameterized ]

```
List<AttributeValue> parameters = new ArrayList<>();
parameters.add(new AttributeValue("Acme Band"));
parameters.add(new AttributeValue("PartiQL Rocks"));

ExecuteStatementRequest request = new ExecuteStatementRequest()
    .withStatement("SELECT * FROM Music WHERE Artist=? AND SongTitle=?")
    .withParameters(parameters);

ExecuteStatementResult result = dynamoDB.executeStatement(request);
```

------
#### [ Python parameterized ]

```
response = dynamodb_client.execute_statement(
    Statement="SELECT * FROM Music WHERE Artist=? AND SongTitle=?",
    Parameters=[
        {'S': 'Acme Band'},
        {'S': 'PartiQL Rocks'}
    ]
)
```

------

**注記**  
前の開始方法セクションの Java の例では、全体にわたってパラメータ化されたステートメントを使用しています。`getPartiQLParameters()` メソッドはパラメータリストを構築し、各ステートメントはインライン値の代わりに `?` プレースホルダーを使用します。