我正在试验 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 检查表状态。
一旦你像它显示的那样添加对描述表的调用,你应该很好。