可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
What is the best way to check if table exists in DynamoDb?
I would appreciate it if the code would be in PHP.
Either active or not.
* Added later as an example to various cases for error code 400
It's very easy to check if the table exist, it can have one of the following
TableStatus => CREATING, ACTIVE, DELETING or UPDATING
but in case i get error 400 it can mean more than one thing.
1) sent null string as a table name by mistake.
[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) syntax error in the command sent to DynamoDB, for example writting tabel_name instead of 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) I would guess but didn't check, if I exceed at that same time the provisioned capacity on the table.
回答1:
You can have a look at "describe_table" of the official PHP SDK. 400 means "does not exist" There is a pretty extensive example in the official documentation. Look at how it is used in the "delete" example, right at the bottom.
http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/LowLevelPHPTableOperationsExample.html
Here is the (stripped) example from the doc
<?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.";
}
}
?>
回答2:
Some of these answers are using the older SDK's and so I thought I'd update this useful question with what I coded up and works well. The newer exceptions really do make this task easier. This function gives you a nice boolean to use in scripts.
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;
}
Hopefully this complete working code helps some of you.
回答3:
I think the answer that solves this with describeTable
is a good one, but fooling around with the status code response makes the code less readable and more confusing.
I chose to check for a tables existence using listTables
. Here are the docs
$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";
回答4:
With DynamoDB you need to parse the contents of the error message in order to know what type of error you received since the status code is almost always 400. Here is a sample function that could work to determine if a table exists. It also allows you to specify a status as well if you want to check if it exists and if it is in a certain state.
<?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.');
}
Update: In the AWS SDK for PHP 2, specific exceptions are thrown by the DynamoDB client, making this way easier to handle. Also, there are "Waiter" objects, including one for this use case (see usage in the unit test) that is designed to sleep until the table exists.
回答5:
The above answers are correct if you just want to know whether the table exist or not. I want to make another helpful point here in case.
One should be very careful in multi-threaded or production level code.
Assuming that one thread deleted the table, then you will still get the answer that the table exists in answer to your query from second thread, until the table is fully deleted. In such case, once the table is deleted, the table handle in second thread is zombie, like the dangling pointer error in C++.
回答6:
With dynamodb cli you can do it very simple as follows:
aws dynamodb describe-table --table-name "my-table"
If the table exists it returns
0 -- Command was successful. There were no errors thrown by either the CLI or by the service the request was made to.
If the table does not exist it returns
255 -- Command failed. There were errors thrown by either the CLI or by the service the request was made to.
See also:
- http://docs.aws.amazon.com/cli/latest/reference/dynamodb/describe-table.html
- http://docs.aws.amazon.com/cli/latest/topic/return-codes.html