Skip to content

Instantly share code, notes, and snippets.

@advance512
Forked from iomz/duplicate_dynamodb_table.py
Created January 20, 2015 23:08
Show Gist options
  • Save advance512/7f6b76219bceb72d809c to your computer and use it in GitHub Desktop.
Save advance512/7f6b76219bceb72d809c to your computer and use it in GitHub Desktop.
A tool to duplicate DynamoDB tables.
from traceback import print_exc
from boto.dynamodb2.exceptions import ValidationException
from boto.dynamodb2.fields import HashKey, RangeKey
from boto.dynamodb2.layer1 import DynamoDBConnection
from boto.dynamodb2.table import Table
from boto.exception import JSONResponseError
from time import sleep
import sys
if len(sys.argv) != 3:
print 'Usage: %s <source_table_name> <destination_table_name>' % sys.argv[0]
sys.exit(1)
src_table = sys.argv[1]
dst_table = sys.argv[2]
DynamoDBConnection.DefaultRegionName = "us-west-2"
ddbc = DynamoDBConnection(aws_access_key_id='AKlalala',
aws_secret_access_key='SDFSDFSDFSDF')
# 1. Read and copy the target table to be copied
table_struct = None
try:
sourceTable = Table(src_table, connection=ddbc)
table_struct = sourceTable.describe()
except JSONResponseError:
print "%s not existing" % src_table
sys.exit(1)
print '*** Reading key schema from %s table' % src_table
src = ddbc.describe_table(src_table)['Table']
hash_key = ''
hash_key_type = ''
range_key = ''
range_key_type = ''
for schema in src['KeySchema']:
if schema['KeyType'] == 'HASH':
hash_key = schema['AttributeName']
hash_key_type = (some_dict['AttributeType'] for some_dict in src['AttributeDefinitions'] if some_dict['AttributeName'] == hash_key).next()
elif schema['KeyType'] == 'RANGE':
range_key = schema['AttributeName']
range_key_type = (some_dict['AttributeType'] for some_dict in src['AttributeDefinitions'] if some_dict['AttributeName'] == range_key).next()
schema = [HashKey(hash_key, data_type=hash_key_type)]
if range_key:
schema.append(RangeKey(range_key, data_type=range_key_type))
# 2. Create the new table
table_struct = None
try:
targetTable = Table(dst_table, schema=schema, connection=ddbc)
table_struct = targetTable.describe()
print 'Table %s already exists' % dst_table
sys.exit(0)
except JSONResponseError:
targetTable = Table.create(dst_table, schema=schema, connection=ddbc)
print '*** Waiting for the new table %s becomes active' % dst_table
sleep(2)
while ddbc.describe_table(dst_table)['Table']['TableStatus'] != 'ACTIVE':
sleep(2)
# 3. Add the items
for index, item in enumerate(sourceTable.scan()):
print "Copying item #%d..." % (index + 1)
new_item = {}
new_item[hash_key] = item[hash_key]
if range_key != '':
new_item[range_key] = item[range_key]
for f in item.keys():
if f in [hash_key, range_key]:
continue
new_item[f] = item[f]
try:
targetTable.put_item(new_item, overwrite=True)
except ValidationException:
print_exc()
print dst_table, new_item
except JSONResponseError:
print ddbc.describe_table(dst_table)['Table']['TableStatus']
@advance512
Copy link
Author

Fixed lots of concrete table specific code in the original, added support for different range/hash key types, and tables with no range key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment