检查DynamoDb中是否存在表的最佳方法是什么?
如果代码是用PHP编写的,我将不胜感激。
活动或不活动。
*稍后作为示例添加到错误代码400 的各种情况中
检查表是否存在非常容易,它可以具有以下内容之一TableStatus=>创建、激活、删除或更新
但如果我得到错误400,它可能意味着不止一件事。
1) 错误地将空字符串作为表名发送。
[x-aws-body]=>{"TableName":"})
[body] => CFSimpleXML Object
(
[__type] => com.amazon.coral.validate#ValidationException
[message] => The paramater 'tableName' must be at least 3 characters long and at most 255 characters long
)
[status] => 400
2) 发送到DynamoDB的命令中存在语法错误,例如写入tabel_name而不是table_name。
[x-aws-body]=>{"TabelName":"test7"})
[body] => CFSimpleXML Object
(
[__type] => com.amazon.coral.validate#ValidationException
[message] => The paramater 'tableName' is required but was not present in the request
)
[status] => 400
3) 我想,但没有检查,如果我同时超过了桌子上的供应容量。
您可以查看官方PHP SDK的"describe_table"400表示"不存在"官方文档中有一个相当广泛的例子。看看它是如何在底部的"删除"示例中使用的。
http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/LowLevelPHPTableOperationsExample.html
以下是文档中的(剥离的)示例
<?php
require_once dirname(__FILE__) . '/sdk/sdk.class.php';
$dynamodb = new AmazonDynamoDB();
$table_name = 'ExampleTable';
$response = $dynamodb->describe_table(array('TableName' => $table_name));
if((integer) $response->status !== 400)
{
$error_type = $response->body->__type;
$error_code = explode('#', $error_type)[1];
if($error_code == 'ResourceNotFoundException')
{
echo "Table ".$table_name." exists.";
}
}
?>
其中一些答案使用的是旧的SDK,所以我想用我编码的内容更新这个有用的问题,并且效果很好。新的异常确实让这项任务变得更容易。这个函数提供了一个很好的布尔值,可以在脚本中使用。
use Aws'DynamoDb'Exception'ResourceNotFoundException; // <-- make sure this line is at the top
public function TableExists($tableName) {
$ddb = DynamoDbClient::factory(array('region' => 'us-east-1')); // EC2 role security
try {
$result = $ddb->describeTable(array(
"TableName" => $tableName
));
} catch (ResourceNotFoundException $e) {
// if this exception is thrown, the table doesn't exist
return false;
}
// no exception thrown? table exists!
return true;
}
希望这个完整的工作代码能帮助到你们中的一些人。
我认为用describeTable
解决这个问题的答案是好的,但篡改状态代码响应会使代码可读性降低,更令人困惑。
我选择使用listTables
检查表是否存在。以下是文档
$tableName = 'my_table';
$client = DynamoDbClient::factory(array('region' => 'us-west-2'));
$response = $client->listTables();
if (!in_array($tableName, $response['TableNames'])) {
// handle non-existence.
// throw an error if you want or whatever
}
// handle existence
echo "Table " . $tableName . " exists";
使用DynamoDB,您需要解析错误消息的内容,以便了解您收到的错误类型,因为状态代码几乎总是400。这里有一个示例函数,可以用来确定表是否存在。如果您想检查它是否存在和是否处于特定状态,它还允许您指定状态。
<?php
function doesTableExist(AmazonDynamoDB $ddb, $tableName, $desiredStatus = null)
{
$response = $ddb->describe_table(array('TableName' => $tableName));
if ($response->isOK()) {
if ($desiredStatus) {
$status = $response->body->Table->TableStatus->to_string();
return ($status === $desiredStatus);
} else {
return true;
}
} elseif ($response->status === 400) {
$error = explode('#', $response->body->__type->to_string());
$error = end($error);
if ($error === 'ResourceNotFoundException') {
return false;
}
}
throw new DynamoDB_Exception('Error performing the DescribeTable operation.');
}
更新:在AWSSDKforPHP2中,DynamoDB客户端会抛出特定的异常,使这种方式更容易处理。此外,还有一些"服务生"对象,其中包括一个用于此用例的对象(请参阅单元测试中的用法),它被设计为睡眠,直到表存在。
使用dynamodb cli,您可以非常简单地完成以下操作:
aws dynamodb describe-table --table-name "my-table"
如果表存在,则返回
0 -- Command was successful. There were no errors thrown by either the CLI or by the service the request was made to.
如果表不存在,则返回
255 -- Command failed. There were errors thrown by either the CLI or by the service the request was made to.
另请参阅:
- http://docs.aws.amazon.com/cli/latest/reference/dynamodb/describe-table.html
- http://docs.aws.amazon.com/cli/latest/topic/return-codes.html
如果您只是想知道表是否存在,那么上面的答案是正确的。我想在这里提出另一个有用的观点以备不时之需。
在多线程或生产级别的代码中应该非常小心。
假设一个线程删除了该表,那么您仍然会从第二个线程得到该表存在的答案,以回答您的查询,直到该表被完全删除。在这种情况下,一旦表被删除,第二个线程中的表句柄就会变成僵尸,就像C++中的悬空指针错误一样。