AWS PHP SDK issue with Dynamodb WriteRequestBatch


AWS PHP SDK issue with Dynamodb WriteRequestBatch

我正在试验 AWS SDK for Dynamodb 的 WriteRequestBatch。下面是我的代码。除了WriteRequestBatch部分之外,一切都可以正常工作。我不知道为什么,想知道社区是否可以在这里帮助我。我可能做错了什么?我尝试在这里谷歌搜索和搜索,只发现了其他 8 个可能相关的问题,但不幸的是没有帮助。

这是我从哪里开始的。

$ddb_client = DynamoDbClient::factory(array(
    'region' => 'us-east-1',
    'key' => 'my_key',
    'secret' => 'my_secret'
));
$ddb_client->createTable(array(
    'TableName' => 'my_table',
    'AttributeDefinitions' => array(
        array(
            'AttributeName' => 'id',
            'AttributeType' => 'S'
        ),
        array(
            'AttributeName' => 'ns',
            'AttributeType' => 'S'
        )
    ),
    'KeySchema' => array(
        array(
            'AttributeName' => 'id',
            'KeyType'       => 'HASH'
        ),
        array(
            'AttributeName' => 'ns',
            'KeyType'       => 'RANGE'
        )
    ),
    'ProvisionedThroughput' => array(
        'ReadCapacityUnits'  => 10,
        'WriteCapacityUnits' => 10
    )
));
$response = $ddb_client->putItem(array(
    "TableName" => "my_table",
    "Item" => array(
        "id" => array("S" => "exp_id"),
        "ns" => array("S" => "exp_ns"),
        "version" => array("N" => "0"),
    ),
));
$item = $response['Item'];
$item['version']['N'] = '1';
$put_batch = WriteRequestBatch::factory($ddb_client);
$put_request = new PutRequest(
    array(
        "Item" => $item,
        "Expected" => array(
            "version" => array(
                "ComparisonOperator" => "EQ",
                "AttributeValueList" => array(
                    array("N" => "0")
                )
            ),
        ),
    ),
    "my_table"
);
$putBatch->add($put_request);
$putBatch->flush();

这比 WriteRequestBatch 有效。我只需要管理批处理来放置自己,而不是使用 WriteRequestBatch 为我做这件事:

$response = $ddb_client->batchWriteItem(array(
    "RequestItems" => array(
        "my_table" => array(
            array(
                "PutRequest" => array(
                    "Item" => $item,
                    "Expected" => array(
                        "version" => array(
                            "ComparisonOperator" => "EQ",
                            "AttributeValueList" => array(
                                array("S" => "0")
                            )
                        ),
                    ),
                )
            )
        )
    )
));

Geek Stocks的答案不完整,但仍然有帮助。您可以处理CreateTable操作的异步方面的一件事是使用 Waiter

$ddb_client->createTable(array('TableName' => 'my_table', ... ));
$ddb_client->waitUntil('TableExists', array('TableName' => 'my_table'));

但是,使用 WriteRequestBatch 类的方式也存在问题。创建PutRequest时,必须传入项,而不是整组PutItem参数。该WriteRequestBatch是对 DynamoDB BatchWriteItem操作的抽象,不允许使用Expected参数之类的操作。如果要这样做,则需要使用单个PutItem/UpdateItem/DeleteItem请求。

以下是正确使用WriteRequestBatch的修改版本:

$putBatch = WriteRequestBatch::factory($ddb_client);
$putBatch->add(new PutRequest($item, 'my_table'));
// ADD MORE...
// ...
// ...
$putBatch->flush();

下面是使用 SDK 用户指南中WriteRequestBatch的另一个示例。


编辑:我刚刚测试的一个更完整的示例,显示了2.7.0之前和之后的版本之间的差异

use Aws'DynamoDb'DynamoDbClient;
use Aws'DynamoDb'Model'BatchRequest'WriteRequestBatch;
use Aws'DynamoDb'Model'BatchRequest'PutRequest;
use Aws'DynamoDb'Model'Item;
$client = DynamoDbClient::factory([/* ... */]);
$batch = WriteRequestBatch::factory($client);
for ($i = 1; $i <= 55; $i++) {
    // FOR ANY SDK VERSION
    // (NOTE: Does not support new M, L, BOOL, and NULL types)
    $item = Item::fromArray(['id' => $i, 'data' => "foo{$i}"]);
    // FOR SDK >= 2.7
    $item = ['id' => ['N' => $i], 'data' => ['S' => "foo{$i}"]];
    $batch->add(new PutRequest($item, 'my-table'));
}
$batch->flush();

因为您当前在代码周围没有任何"尝试/捕获"错误处理,所以您可能无法获得有关错误的良好信息。

我在您的代码上放置了 try/catch 块,发现该表创建得很好,但对 putItem 的调用失败,原因如下:未找到请求的资源

当您创建表时,它不会立即可用。您必须暂停,直到它可用。AWS 文档的这一段很好地解释了这一点:

创建表是一个异步操作。收到创建表请求后,DynamoDB 会立即返回表状态为 正在创建的响应。创建表后,DynamoDB 会将表状态设置为活动。您只能对 ACTIVE 表执行读取和写入操作。您可以使用描述表 API 检查表状态。

一旦你像它显示的那样添加对描述表的调用,你应该很好。