AWS SDK for PHP で DynamoDB する
問題
phpでDynamoDBしたいです。
答え
準備
テーブル作成: DynamoDBは、極論テーブルは1個に全部突っ込めみたいな世界なので tbl など適当な名前でもいいでしょう。単純なキーとデータの組み合わせならパーティションキーのみソートキーなしのテーブルもあり。
下のほうの例では、パーティションキー名をpkとしているが、そういうルールがあるわけではない。設計は自由。
接続ユーザー作成: IAMユーザーを作成。DynamoDBへの権限を付与。アクセスキー、シークレットアクセスキーを控えておく。
AWS SDK for PHP をインストール
- お手軽なのは aws.phar をダウンロードして
require 'aws.phar';
- composerで管理していたら
composer require aws/aws-sdk-php
- composerなしなら zip版を解凍して
require 'aws-autoloader.php';
読み込む
DynamoDbClientを使って getItemやqueryするだけなら以下1行でよい。
use Aws\DynamoDb\DynamoDbClient;
必要に応じて以下など。
use Aws\DynamoDb\DynamoDbClient; use Aws\DynamoDb\Marshaler;
接続情報の管理
接続情報は以下で設定できる。
- 実行ユーザーのホームディレクトリの ~/.aws/credentials ファイル
- 環境変数 AWS_SHARED_CREDENTIALS_FILE で指定したファイル
- 環境変数で設定する AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN
- プログラム内で引数で直接
設定方法は多数ある。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html
php で環境変数を設定するなら putenv() でできる。
putenv('AWS_ACCESS_KEY_ID=AKIAI44QH8DHBEXAMPLE'); putenv('AWS_SECRET_ACCESS_KEY=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY');
DynamoDBに接続する
接続情報が ~/.aws/credentials や環境変数の設定でよかったら、credentials など省略可能。
以下ではプログラム内で引数で渡している。
<?php require 'aws-autoloader.php'; use Aws\DynamoDb\DynamoDbClient; $client = new DynamoDbClient([ 'region' => 'ap-northeast-1', 'version' => 'latest', 'credentials' => [ 'key' => $access_key, 'secret' => $secret_key, ], 'http' => [ 'timeout' => 5, ], ]);
パラメータはこちらを参照
https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.AwsClient.html#___construct
‘version’ => ‘latest’ など省略でしてよさそうなものが必須項目だったりする。省略するとエラーになる。
上の例では timeout を指定したが、これは任意項目。省略可能。
DynamoDBに問い合わせる
getItem
プライマリキーなどで項目を取得
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#getitem
<?php $result = $client->getItem([ 'Key' => [ 'pk' => [ 'S' => 'test' ] ], 'TableName' => 'tbl' ]); var_dump($result);
結果
object(Aws\Result)#132 (2) { ["data":"Aws\Result":private]=> array(2) { ["Item"]=> array(2) { ["pk"]=> array(1) { ["S"]=> string(4) "test" } ["xxxx"]=> array(1) { ["S"]=> string(32) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } ["@metadata"]=> array(4) { ["statusCode"]=> int(200) ["effectiveUri"]=> string(45) "https://dynamodb.ap-northeast-1.amazonaws.com" ["headers"]=> 以下省略
結果は $result[‘Item’][‘xxxx’][‘S’] などで取得できる。
Aws\Result オブジェクトなので、 $result->get(‘Item’); でも取得できる。
query
インデックスを使って問い合わせ
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#query
<?php $result = $client->query([ 'TableName' => 'tbl', 'IndexName' => 'xxxx-index', 'KeyConditionExpression' => 'xxxx = :xxxx', 'ExpressionAttributeValues' => [ ':xxxx' => [ 'S' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ], ], 'Limit' => 10, ]);
結果
object(Aws\Result)#144 (2) { ["data":"Aws\Result":private]=> array(4) { ["Items"]=> array(1) { [0]=> array(2) { ["pk"]=> array(1) { ["S"]=> string(4) "test" } ["xxxx"]=> array(1) { ["S"]=> string(32) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } } ["Count"]=> int(1) ["ScannedCount"]=> int(1) ["@metadata"]=> 以下省略
結果は $result[‘Items’][0][‘xxxx’][‘S’] などで取得できる。
Aws\Result オブジェクトなので、 $result->get(‘Items’); でも取得できる。
結果が複数返ってくることもある。
scan
コストが高いので注意
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#scan
<?php $result = $client->scan([ 'TableName' => 'tbl', 'FilterExpression' => 'xxxx = :xxxx', 'ExpressionAttributeValues' => [ ':h' => [ 'S' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ], ], 'Limit' => 10, ]);
結果はqueryと同様。
putItem
項目を作成
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#putitem
<?php $client->putItem([ 'TableName' => 'tbl', 'Item' => [ 'pk' => [ 'S' => 'abcdefg' ], '属性aaa' => [ 'S' => '属性値属性値属性値属性値' ], ], ]);
プライマリキーが重複していたら作成できない。
updateItem
項目を作成(存在しなければ作成、存在すれば更新)
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#updateitem
<?php $client->updateItem([ 'TableName' => 'tbl', 'AttributeUpdates' => [ '属性名1234' => [ 'Value' => [ 'S' => '値値値値値値値値値値値値値値' ], ], ], 'Key' => [ 'pk' => [ 'S' => 'パーティションキーなんとか' ], ] ]);
プライマリキーが重複していたら更新。項目が存在しなかったら作成。
deleteItem
項目を削除
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#updateitem
<?php $client->deleteItem([ 'TableName' => 'tbl', 'Key' => [ 'pk' => [ 'S' => $_REQUEST['s'] ], ], ]);
DynamoDBのその他のメモ – 予約語
予約語が多数ある。
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
data, list, hash, user などの単語を属性名に使うと、データの保存はできるのに、queryするときに「予約語だよ」と言われてエラーになるなどやや面倒。
Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: user
予約語のエラーを回避するには、ExpressionAttributeNames を使うなどが必要になる。
$db->scan([ 'TableName' => 'tbl', 'ExpressionAttributeNames' => ['#U' => 'user'], 'FilterExpression' => '#U = :u', 'ExpressionAttributeValues' => [ ':u' => ['S' => '太郎君'], ], 'Limit' => 10, ]);
DynamoDBのその他のメモ – 問い合わせのSとかNとか
問い合わせの中にみられるSとかNとかの文字は何なのかというと、データ型記述子です。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
S – 文字列、N – 数値、BOOL – 真偽値 … などを表しています。
コメント