0
votes

The code below is intended to create a test database, but first delete it if it exists.

First, the version information:

Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto
>>> print(boto.Version)
2.19.0
>>> 

Running the code works the first time, but run it again immediately and it reports the following error:

[email protected]:~/stat/tools$ python js-dbd-test.py 
DynamoDB table: emails
{u'Table': {u'AttributeDefinitions': [{u'AttributeName': u'messageid', u'AttributeType': u'S'}], u'ProvisionedThroughput': {u'NumberOfDecreasesToday': 0, u'WriteCapacityUnits': 1, u'ReadCapacityUnits': 1}, u'TableSizeBytes': 153, u'TableName': u'emails', u'TableStatus': u'ACTIVE', u'KeySchema': [{u'KeyType': u'HASH', u'AttributeName': u'messageid'}], u'ItemCount': 1, u'CreationDateTime': 1366430267.719}}
DynamoDB table: notes
{u'Table': {u'ProvisionedThroughput': {u'NumberOfDecreasesToday': 0, u'WriteCapacityUnits': 1, u'ReadCapacityUnits': 1}, u'TableSizeBytes': 0, u'ItemCount': 0, u'TableName': u'notes', u'TableStatus': u'DELETING'}}
DynamoDB table: users
{u'Table': {u'AttributeDefinitions': [{u'AttributeName': u'submissionid', u'AttributeType': u'S'}, {u'AttributeName': u'userid', u'AttributeType': u'S'}], u'ProvisionedThroughput': {u'NumberOfDecreasesToday': 0, u'WriteCapacityUnits': 1, u'ReadCapacityUnits': 1}, u'TableSizeBytes': 0, u'TableName': u'users', u'TableStatus': u'ACTIVE', u'KeySchema': [{u'KeyType': u'HASH', u'AttributeName': u'submissionid'}, {u'KeyType': u'RANGE', u'AttributeName': u'userid'}], u'ItemCount': 0, u'CreationDateTime': 1386161175.525}}
Deleting table....
waiting....
ACTIVE
ACTIVE
Traceback (most recent call last):
  File "js-dbd-test.py", line 53, in <module>
    notes.delete()
  File "/home/ubuntu/stat/local/lib/python2.7/site-packages/boto/dynamodb2/table.py", line 341, in delete
    self.connection.delete_table(self.table_name)
  File "/home/ubuntu/stat/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 519, in delete_table
    body=json.dumps(params))
  File "/home/ubuntu/stat/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1487, in make_request
    retry_handler=self._retry_handler)
  File "/home/ubuntu/stat/local/lib/python2.7/site-packages/boto/connection.py", line 899, in _mexe
    status = retry_handler(response, i, next_sleep)
  File "/home/ubuntu/stat/local/lib/python2.7/site-packages/boto/dynamodb2/layer1.py", line 1530, in _retry_handler
    data)
boto.exception.JSONResponseError: JSONResponseError: 400 Bad Request
{u'message': u'Attempt to change a resource which is still in use: Table is being deleted: notes', u'__type': u'com.amazonaws.dynamodb.v20120810#ResourceInUseException'}
(stat)[~/stat/tools]
[email protected]:~/stat/tools$ 

Can anyone suggest what I am doing wrong and a way to reliably delete and recreate Dynamodb databases?

from boto.dynamodb2 import regions
from boto.dynamodb2.fields import HashKey, RangeKey, KeysOnlyIndex
from boto.dynamodb2.layer1 import DynamoDBConnection
from boto.dynamodb2.table import Table
from boto.dynamodb2.types import NUMBER, STRING
import boto
global config
import ConfigParser
import sys
import uuid
from time import sleep

config = ConfigParser.ConfigParser()
config.read('~/status.conf')

connection=DynamoDBConnection(
    aws_access_key_id=config.get("statusapplication", "accesskeyid"),
    aws_secret_access_key=config.get("statusapplication", "secretaccesskey"),
    host='dynamodb.us-west-1.amazonaws.com',
    region='us-west-1',
)

#get and print list of tables
tablenames = connection.list_tables().get('TableNames', None)
for table in tablenames:
    print('DynamoDB table: %s' % table)
    print(connection.describe_table(table))


# delete table if it exists
if 'notes' in tablenames:
    print('Deleting table....')
    notes = Table('notes', connection=connection)
    tablestatus = ''
    # gotta wait for the table to be ACTIVE before we can delete it
    count = 0
    while tablestatus != 'ACTIVE':
        print('waiting....')
        sleep(2)
        tabledescription = connection.describe_table(table)
        tablestatus = tabledescription['Table']['TableStatus']
        print(tablestatus)
        if count == 5:
            print('Timeout waiting for table to become ACTIVE, exiting.')
            sys.exit(1)
        count += 1
    sleep(5)
    tablestatus = tabledescription['Table']['TableStatus']
    print(tablestatus)
    notes = None
    notes = Table('notes', connection=connection)
    notes.delete()


    # wait for the table delete to complete
    count = 0
    tabledescription = connection.describe_table(table)
    tablestatus = tabledescription['Table']['TableStatus']
    while tablestatus == 'DELETING':
        sleep(2)
        tabledescription = connection.describe_table(table)
        tablestatus = tabledescription['Table']['TableStatus']
        print(tablestatus)
        print(tabledescription)
        if count == 5:
            print('Table did not delete in under 10 seconds, exiting.')
            sys.exit(1)
        print('waiting....')
        count += 1



# create table if it does not exist
if 'notes' not in tablenames:
    print('Creating table....')
    notes = Table.create('notes', schema=[
        HashKey('noteid', data_type=STRING),
    ], throughput={
        'read': 1,
        'write': 1,
    }, connection=connection)

    # wait for the table creation to complete
    count = 0
    tablestatus = ''
    while tablestatus != 'ACTIVE':
        sleep(2)
        tabledescription = connection.describe_table(table)
        tablestatus = tabledescription['Table']['TableStatus']
        print(tablestatus)
        print(tabledescription)
        if count == 5:
            print('Table did not create in under 10 seconds, exiting.')
            sys.exit(1)
        print('waiting....')
        count += 1

# get the table
notes = Table('notes', connection=connection)

sys.exit(0)
2

2 Answers

1
votes

You can use a waiter for that, in order to wait till the operation is actually done:

import boto3
client = boto3.client('dynamodb')

client.delete_table(TableName='foo')

client.get_waiter('table_not_exists').wait(TableName='foo')
print ("table deleted")

Same when creating a table with:

client.get_waiter('table_exists').wait(TableName='foo')
0
votes

Your issue is that deleting the database takes time. So you basically will need to wait for the database to be deleted before you go to create the new database with the same name. I am dealing with this right now. Alternatively you might clear the table entries instead. Good luck!