@@ -162,6 +162,51 @@ def update_provisioned_throughput(conn, table_name, read_capacity, write_capacit
162162 if wait :
163163 wait_for_active_table (conn , table_name , "updated" )
164164
165+ def do_empty (conn , table_name ):
166+ logging .info ("Starting Empty for " + table_name + ".." )
167+
168+ # get table schema
169+ logging .info ("Fetching table schema for " + table_name )
170+ table_data = conn .describe_table (table_name )
171+
172+ table_desc = table_data ["Table" ]
173+ table_attribute_definitions = table_desc ["AttributeDefinitions" ]
174+ table_key_schema = table_desc ["KeySchema" ]
175+ original_read_capacity = table_desc ["ProvisionedThroughput" ]["ReadCapacityUnits" ]
176+ original_write_capacity = table_desc ["ProvisionedThroughput" ]["WriteCapacityUnits" ]
177+ table_local_secondary_indexes = table_desc .get ("LocalSecondaryIndexes" )
178+ table_global_secondary_indexes = table_desc .get ("GlobalSecondaryIndexes" )
179+
180+ table_provisioned_throughput = {"ReadCapacityUnits" : int (original_read_capacity ), "WriteCapacityUnits" : int (original_write_capacity )}
181+
182+ logging .info ("Deleting Table " + table_name )
183+
184+ delete_table (conn , sleep_interval , table_name )
185+
186+ logging .info ("Creating Table " + table_name )
187+
188+ while True :
189+ try :
190+ conn .create_table (table_attribute_definitions , table_name , table_key_schema , table_provisioned_throughput , table_local_secondary_indexes , table_global_secondary_indexes )
191+ break
192+ except boto .exception .JSONResponseError , e :
193+ if e .body ["__type" ] == "com.amazonaws.dynamodb.v20120810#LimitExceededException" :
194+ logging .info ("Limit exceeded, retrying creation of " + destination_table + ".." )
195+ time .sleep (sleep_interval )
196+ elif e .body ["__type" ] == "com.amazon.coral.availability#ThrottlingException" :
197+ logging .info ("Control plane limit exceeded, retrying creation of " + destination_table + ".." )
198+ time .sleep (sleep_interval )
199+ else :
200+ logging .exception (e )
201+ sys .exit (1 )
202+
203+ # wait for table creation completion
204+ wait_for_active_table (conn , table_name , "created" )
205+
206+
207+
208+ logging .info ("Recreation of " + table_name + " completed. Time taken: " + str (datetime .datetime .now ().replace (microsecond = 0 ) - start_time ))
209+
165210def do_backup (conn , table_name , read_capacity ):
166211 logging .info ("Starting backup for " + table_name + ".." )
167212
@@ -330,8 +375,8 @@ def do_restore(conn, sleep_interval, source_table, destination_table, write_capa
330375 logging .info ("Restore for " + source_table + " to " + destination_table + " table completed. Time taken: " + str (datetime .datetime .now ().replace (microsecond = 0 ) - start_time ))
331376
332377# parse args
333- parser = argparse .ArgumentParser (description = "Simple DynamoDB backup/restore." )
334- parser .add_argument ("-m" , "--mode" , help = "'backup' or 'restore'" )
378+ parser = argparse .ArgumentParser (description = "Simple DynamoDB backup/restore/empty ." )
379+ parser .add_argument ("-m" , "--mode" , help = "'backup' or 'restore' or 'empty' " )
335380parser .add_argument ("-r" , "--region" , help = "AWS region to use, e.g. 'us-west-1'. Use '" + LOCAL_REGION + "' for local DynamoDB testing." )
336381parser .add_argument ("-s" , "--srcTable" , help = "Source DynamoDB table name to backup or restore from, use 'tablename*' for wildcard prefix selection or '*' for all tables." )
337382parser .add_argument ("-d" , "--destTable" , help = "Destination DynamoDB table name to backup or restore to, use 'tablename*' for wildcard prefix selection (defaults to use '-' separator) [optional, defaults to source]" )
@@ -430,4 +475,22 @@ def do_restore(conn, sleep_interval, source_table, destination_table, write_capa
430475 else :
431476 delete_table (conn , sleep_interval , dest_table )
432477 do_restore (conn , sleep_interval , args .srcTable , dest_table , args .writeCapacity )
478+ elif args .mode == "empty" :
479+ if args .srcTable .find ("*" ) != - 1 :
480+ matching_backup_tables = get_table_name_matches (conn , args .srcTable , prefix_separator )
481+ logging .info ("Found " + str (len (matching_backup_tables )) + " table(s) in DynamoDB host to empty: " + ", " .join (matching_backup_tables ))
482+
483+ threads = []
484+ for table_name in matching_backup_tables :
485+ t = threading .Thread (target = do_empty , args = (conn , table_name ))
486+ threads .append (t )
487+ t .start ()
488+ time .sleep (THREAD_START_DELAY )
489+
490+ for thread in threads :
491+ thread .join ()
492+
493+ logging .info ("Empty of table(s) " + args .srcTable + " completed!" )
494+ else :
495+ do_empty (conn , args .srcTable )
433496
0 commit comments