What is the best way to check if table exists in D

2019-04-06 09:05发布

问题:

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