简体   繁体   English

Dynamodb WriteRequestBatch的AWS PHP SDK问题

[英]AWS PHP SDK issue with Dynamodb WriteRequestBatch

I am experimenting with WriteRequestBatch from AWS SDK for Dynamodb. 我正在试验适用于Dynamodb的AWS开发工具包的WriteRequestBatch。 Below is my code. 下面是我的代码。 Everything works except the WriteRequestBatch part. 除WriteRequestBatch部分外,其他所有东西都起作用。 I have no clue why, and was wondering if the community could help me out here. 我不知道为什么,并且想知道社区是否可以在这里帮助我。 What might I be doing wrong? 我可能做错了什么? I have tried googling and searching here and found only 8 other questions that could be related but unfortunately were of no help. 我尝试在此处进行谷歌搜索和搜索,但发现只有8个其他相关问题,但不幸的是这没有帮助。

This is where I started from. 是我的起点。

$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();

This works instead of WriteRequestBatch. 这代替了WriteRequestBatch。 I will just have to manage batches to put myself than use WriteRequestBatch doing it for me: 与使用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")
                            )
                        ),
                    ),
                )
            )
        )
    )
));

Because you currently do not have any "try / catch" error handling around your code you are likely not getting good information on your error. 因为您当前在代码周围没有任何“尝试/捕获”错误处理,所以您可能无法获得有关错误的良好信息。

I placed try/catch blocks on your code and found that the table creates just fine but that the call to putItem fails for the following reason: Requested resource not found 我在代码上放置了try / catch块,发现该表创建得很好,但是对putItem的调用由于以下原因而失败: 找不到请求的资源

When you create a table it is NOT immediately available. 创建表时,它不是立即可用的。 You have to pause until it becomes available. 您必须暂停直到可用。 This paragraph of the AWS docs explains this nicely: AWS文档的这一段很好地解释了这一点:

CreateTable is an asynchronous operation. CreateTable是一个异步操作。 Upon receiving a CreateTable request, DynamoDB immediately returns a response with a TableStatus of CREATING . 收到CreateTable请求后,DynamoDB立即返回TableStatus为CREATING的响应。 After the table is created, DynamoDB sets the TableStatus to ACTIVE . 创建表后,DynamoDB将TableStatus设置为ACTIVE。 You can perform read and write operations only on an ACTIVE table. 您只能在ACTIVE表上执行读取和写入操作。 You can use the DescribeTable API to check the table status. 您可以使用DescribeTable API来检查表状态。

Once you add the call to DescribeTable like it shows, you should be good. 将调用添加到如所示的DescribeTable后,您应该会很好。

The answer by Geek Stocks is incomplete, but still helpful. Geek Stocks答案虽然不完整,但仍然很有帮助。 One thing you can do handle the asynchronous aspects of the CreateTable operation is to use a Waiter : 您可以处理CreateTable操作的异步方面的一件事是使用Waiter

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

However , there is also a problem with how you are using the WriteRequestBatch class. 但是 ,如何使用WriteRequestBatch类也存在问题。 When you create a PutRequest , you must pass in the item, not a whole set of PutItem parameters. 创建PutRequest ,必须传入项目,而不是完整的PutItem参数集。 The WriteRequestBatch is an abstraction over DynamoDB's BatchWriteItem operation , which does not allow things like the Expected parameter. WriteRequestBatch是DynamoDB的BatchWriteItem操作的抽象,该操作不允许使用Expected参数。 If you want to do that, then you need to use individual PutItem / UpdateItem / DeleteItem requests. 如果要这样做,则需要使用单独的PutItem / UpdateItem / DeleteItem请求。

Here is a modified version of your usage of WriteRequestBatch that is correct: 这是正确使用WriteRequestBatch的修改版本:

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

Here is another example of using the WriteRequestBatch from the SDK's User Guide. 这是SDK用户指南中使用WriteRequestBatch另一个示例。


EDIT : One more complete example that works that I just tested, that shows the difference between versions prior to 2.7.0 and afterwards 编辑 :我刚刚测试过的一个更完整的示例工作,它显示了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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM