aiotu / terseq
AWS DynamoDB 查询构建器
v0.1.2
2024-09-24 16:19 UTC
Requires
- php: ^8.3
- aws/aws-sdk-php: ^3
- loophp/collection: ^7.6
- nesbot/carbon: ^3 || ^2
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^11.1
- symfony/var-dumper: ^7.0
README
本文件提供了如何利用 Terseq 库使用 AWS SDK for PHP 构建 AWS DynamoDB 查询的全面指南。
功能
Terseq 支持构建以下 DynamoDB 操作的查询
单项操作
查询操作
事务
批量
为什么我应该使用这个库?
AWS SDK for PHP 是处理 AWS 服务的强大工具,但由于其复杂性,使用起来可能会有些挑战。它需要编写大量模板代码来构建和执行查询。Terseq 通过提供构建 DynamoDB 操作查询的流畅接口来简化这一过程。它还支持单表设计,这是 DynamoDB 的推荐做法。
安装
要安装 Terseq 包,请使用 Composer 在您的项目目录中运行以下命令
composer require aiotu/terseq
使用方法
初始化
通过 AWS SDK 和 DatabaseManager 创建客户端
$client = new \Aws\DynamoDb\DynamoDbClient([ 'region' => 'us-west-2', 'version' => 'latest', ]); $manager = new \Terseq\DatabaseManager($client, new Marshaler());
操作
GetItem
$manager->getItem() ->table(['Books', 'BookId']) ->pk('super-cool-id') ->dispatch();
PutItem
$manager->putItem() ->table(['Books', 'BookId']) ->item([ 'BookId' => 'super-cool-id', 'Title' => 'Super Cool Book', 'Author' => 'Super Cool Author', ]) ->dispatch();
UpdateItem
$manager->updateItem() ->table(['Books', 'BookId']) ->pk('super-cool-id') ->set('Title', 'Super Cool Book Updated') ->set('Author', 'Super Cool Author Updated') ->dispatch();
DeleteItem
$manager->deleteItem() ->table(['Books', 'BookId']) ->pk('super-cool-id') ->dispatch();
Query
$result = $manager->query() ->table(['Books', 'BookId']) ->pk('super-cool-id') ->consistentRead() ->disaptch();
TransactGetItems
use Terseq\Builders\Operations\TransactGetItems\Operations\Get; $manager->transactGetItems() ->get( [ static fn (Get $get) => $get->pk('super-cool-id1'), static fn (Get $get) => $get->pk('super-cool-id2'), ], table: ['Books', 'BookId'], ) ->dispatch();
TransactWriteItems
use Terseq\Builders\Operations\TransactWriteItems\Operations\Delete; use Terseq\Builders\Operations\TransactWriteItems\Operations\Put; use Terseq\Builders\Operations\TransactWriteItems\Operations\Update; $manager->transactWriteItems() ->put( [ fn (Put $put) => $put->item([ 'BookId' => 'super-book1', 'Author' => 'Unknown', ]), fn (Put $put) => $put->item([ 'BookId' => 'super-book-2', 'Author' => 'Incognito', ]), ], table: ['Books', 'BookId'], ) ->update( fn (Update $update) => $update ->pk('super-book-3') ->set('Author', 'Incognito'), table: ['Books', 'BookId'], ) ->delete( fn (Delete $delete) => $delete->pk('super-book-4'), table: ['Books', 'BookId'], ) ->dispatch();
BatchGetItem
$manager->batchGetItem() ->get( [ 'BookId' => 'super-book-1', 'Author' => 'Unknown', ], table: ['Books', 'BookId'], ) ->get( [ 'BookId' => 'super-book-2', 'Author' => 'Incognito', ], table: ['Books', 'BookId'], ) ->dispatch();
BatchWriteItem
$manager->batchWriteItem() ->put( [ 'BookId' => 'super-book-1', 'Author' => 'Unknown', ], table: ['Books', 'BookId'], ) ->put( [ 'BookId' => 'super-book-2', 'Author' => 'Incognito', ], table: ['Books', 'BookId'], ) ->delete( [ 'BookId' => 'super-book-3', ], table: ['Books', 'BookId'], ) ->dispatch();
表
表作为对象(推荐)
使用表对象的示例
use Terseq\Builders\Table; class Books extends Table { public function getTableName(): string { return 'Books'; } public function getKeys(): Keys { return new Keys(partitionKey: 'BookId', sortKey: null); } }
使用 二级索引 的示例
use Terseq\Builders\Table; class BooksTable extends Table { /** * Table name */ public function getTableName(): string { return 'Books'; } /** * Partition key and sort key (optional) */ public function getKeys(): Keys { return new Keys(partitionKey: 'BookId', sortKey: 'ReleaseDate'); } /** * Secondary index map (optional) also known as GSI and LSI */ public function getSecondaryIndexMap(): ?array { return [ 'AuthorIndex' => new Keys(partitionKey: 'AuthorId', sortKey: 'AuthorBornYear'), 'GenreIndex' => new Keys(partitionKey: 'GenreId', sortKey: 'GenreName'), 'LsiExample' => new Keys(partitionKey: 'BookId', sortKey: 'AuthorBornYear'), ]; } }
表作为数组
table(table: ['TableName', 'PartitionKey', 'SortKey']);
或
table(table: ['TableName', 'PartitionKey']); // Sort key by default is null
或
table(table: ['TableName']); // throws exception, because PartitionKey is required
或
table(table: [ 'table' => 'TableName', 'pk' => 'PartitionKey', 'sk' => 'SortKey', ]);
单表设计(推荐)
库支持 单表设计。
使用单表设计的示例
$manager = new \Terseq\DatabaseManager( client: $client, marshaler: new Marshaler(), singleTable: new class extends \Terseq\Builders\Table { public function getTableName(): string { return 'Books'; } public function getKeys(): Keys { return new Keys(partitionKey: 'BookId'); } }, );
这就完了!现在您可以构建查询而无需传递表名和键。
使用方法
// Query $manager->getItem()->pk('super-cool-id')->disaptch(); $manager->batchWriteItem() ->put( [ 'BookId' => 'super-book-1', 'Author' => 'Unknown', ], ) ->put( [ 'BookId' => 'super-book-2', 'Author' => 'Incognito', ], ) ->delete( [ 'BookId' => 'super-book-3', ], ) ->dispatch();
与 AWS SDK 的比较
使用 AWS SDK 的示例
$client->updateItem( [ 'TableName' => 'Books', 'UpdateExpression' => 'SET #Title = :title_0, #Author = :author_0', 'ExpressionAttributeNames' => [ '#Title' => 'Title', '#Author' => 'Author', ], 'ExpressionAttributeValues' => [ ':title_0' => [ 'S' => 'Super Cool Book Updated', ], ':author_0' => [ 'S' => 'Super Cool Author Updated', ], ], 'Key' => [ 'BookId' => [ 'S' => 'super-cool-id', ], ], ], );
使用 Terseq 的示例
执行相同操作
$manager->updateItem() ->table(['Books', 'BookId']) ->pk('super-cool-id') ->set('Title', 'Super Cool Book Updated') ->set('Author', 'Super Cool Author Updated') ->dispatch();