@@ -442,165 +442,172 @@ def do_restore(conn, sleep_interval, source_table, destination_table, write_capa
442442 logging .info ("Empty schema of " + source_table + " table created. Time taken: " + str (datetime .datetime .now ().replace (microsecond = 0 ) - start_time ))
443443
444444
445- # parse args
446- parser = argparse .ArgumentParser (description = "Simple DynamoDB backup/restore/empty." )
447- parser .add_argument ("-m" , "--mode" , help = "'backup' or 'restore' or 'empty'" )
448- parser .add_argument ("-r" , "--region" ,
449- help = "AWS region to use, e.g. 'us-west-1'. Use '" + LOCAL_REGION + "' for local DynamoDB testing" )
450- parser .add_argument ("--host" , help = "Host of local DynamoDB [required only for local]" )
451- parser .add_argument ("--port" , help = "Port of local DynamoDB [required only for local]" )
452- parser .add_argument ("--accessKey" , help = "Access key of local DynamoDB [required only for local]" )
453- parser .add_argument ("--secretKey" , help = "Secret key of local DynamoDB [required only for local]" )
454- parser .add_argument ("-p" , "--profile" ,
455- help = "AWS credentials file profile to use. Allows you to use a profile instead of accessKey, secretKey authentication" )
456- parser .add_argument ("-s" , "--srcTable" ,
457- help = "Source DynamoDB table name to backup or restore from, use 'tablename*' for wildcard prefix selection or '*' for all tables" )
458- parser .add_argument ("-d" , "--destTable" ,
459- help = "Destination DynamoDB table name to backup or restore to, use 'tablename*' for wildcard prefix selection (defaults to use '-' separator) [optional, defaults to source]" )
460- parser .add_argument ("--prefixSeparator" , help = "Specify a different prefix separator, e.g. '.' [optional]" )
461- parser .add_argument ("--noSeparator" , action = 'store_true' ,
462- help = "Overrides the use of a prefix separator for backup wildcard searches [optional]" )
463- parser .add_argument ("--readCapacity" ,
464- help = "Change the temp read capacity of the DynamoDB table to backup from [optional]" )
465- parser .add_argument ("--writeCapacity" ,
466- help = "Change the temp write capacity of the DynamoDB table to restore to [defaults to " + str (
467- RESTORE_WRITE_CAPACITY ) + ", optional]" )
468- parser .add_argument ("--schemaOnly" , action = "store_true" , default = False ,
469- help = "Backup or restore the schema only. Do not backup/restore data. Can be used with both backup and restore modes. Cannot be used with the --dataOnly [optional]" )
470- parser .add_argument ("--dataOnly" , action = "store_true" , default = False ,
471- help = "Restore data only. Do not delete/recreate schema [optional for restore]" )
472- parser .add_argument ("--skipThroughputUpdate" , action = "store_true" , default = False ,
473- help = "Skip updating throughput values across tables [optional]" )
474- parser .add_argument ("--dumpPath" , help = "Directory to place and search for DynamoDB table backups (defaults to use '" + str (DATA_DUMP ) + "') [optional]" , default = str (DATA_DUMP ))
475- parser .add_argument ("--log" , help = "Logging level - DEBUG|INFO|WARNING|ERROR|CRITICAL [optional]" )
476- args = parser .parse_args ()
477-
478- # set log level
479- log_level = LOG_LEVEL
480- if args .log is not None :
481- log_level = args .log .upper ()
482- logging .basicConfig (level = getattr (logging , log_level ))
483-
484-
485- # Check to make sure that --dataOnly and --schemaOnly weren't simultaneously specified
486- if args .schemaOnly and args .dataOnly :
487- logging .info ("Options --schemaOnly and --dataOnly are mutually exclusive." )
488- sys .exit (1 )
489-
490-
491- # instantiate connection
492- if args .region == LOCAL_REGION :
493- conn = DynamoDBConnection (aws_access_key_id = args .accessKey , aws_secret_access_key = args .secretKey , host = args .host ,
494- port = int (args .port ), is_secure = False )
495- sleep_interval = LOCAL_SLEEP_INTERVAL
496- else :
497- if not args .profile :
498- conn = boto .dynamodb2 .connect_to_region (args .region , aws_access_key_id = args .accessKey ,
499- aws_secret_access_key = args .secretKey )
500- sleep_interval = AWS_SLEEP_INTERVAL
445+ def main ():
446+ global args , sleep_interval , start_time
447+ # parse args
448+ parser = argparse .ArgumentParser (description = "Simple DynamoDB backup/restore/empty." )
449+ parser .add_argument ("-m" , "--mode" , help = "'backup' or 'restore' or 'empty'" )
450+ parser .add_argument ("-r" , "--region" ,
451+ help = "AWS region to use, e.g. 'us-west-1'. Use '" + LOCAL_REGION + "' for local DynamoDB testing" )
452+ parser .add_argument ("--host" , help = "Host of local DynamoDB [required only for local]" )
453+ parser .add_argument ("--port" , help = "Port of local DynamoDB [required only for local]" )
454+ parser .add_argument ("--accessKey" , help = "Access key of local DynamoDB [required only for local]" )
455+ parser .add_argument ("--secretKey" , help = "Secret key of local DynamoDB [required only for local]" )
456+ parser .add_argument ("-p" , "--profile" ,
457+ help = "AWS credentials file profile to use. Allows you to use a profile instead of accessKey, secretKey authentication" )
458+ parser .add_argument ("-s" , "--srcTable" ,
459+ help = "Source DynamoDB table name to backup or restore from, use 'tablename*' for wildcard prefix selection or '*' for all tables" )
460+ parser .add_argument ("-d" , "--destTable" ,
461+ help = "Destination DynamoDB table name to backup or restore to, use 'tablename*' for wildcard prefix selection (defaults to use '-' separator) [optional, defaults to source]" )
462+ parser .add_argument ("--prefixSeparator" , help = "Specify a different prefix separator, e.g. '.' [optional]" )
463+ parser .add_argument ("--noSeparator" , action = 'store_true' ,
464+ help = "Overrides the use of a prefix separator for backup wildcard searches [optional]" )
465+ parser .add_argument ("--readCapacity" ,
466+ help = "Change the temp read capacity of the DynamoDB table to backup from [optional]" )
467+ parser .add_argument ("--writeCapacity" ,
468+ help = "Change the temp write capacity of the DynamoDB table to restore to [defaults to " + str (
469+ RESTORE_WRITE_CAPACITY ) + ", optional]" )
470+ parser .add_argument ("--schemaOnly" , action = "store_true" , default = False ,
471+ help = "Backup or restore the schema only. Do not backup/restore data. Can be used with both backup and restore modes. Cannot be used with the --dataOnly [optional]" )
472+ parser .add_argument ("--dataOnly" , action = "store_true" , default = False ,
473+ help = "Restore data only. Do not delete/recreate schema [optional for restore]" )
474+ parser .add_argument ("--skipThroughputUpdate" , action = "store_true" , default = False ,
475+ help = "Skip updating throughput values across tables [optional]" )
476+ parser .add_argument ("--dumpPath" ,
477+ help = "Directory to place and search for DynamoDB table backups (defaults to use '" + str (
478+ DATA_DUMP ) + "') [optional]" , default = str (DATA_DUMP ))
479+ parser .add_argument ("--log" , help = "Logging level - DEBUG|INFO|WARNING|ERROR|CRITICAL [optional]" )
480+ args = parser .parse_args ()
481+ # set log level
482+ log_level = LOG_LEVEL
483+ if args .log is not None :
484+ log_level = args .log .upper ()
485+ logging .basicConfig (level = getattr (logging , log_level ))
486+ # Check to make sure that --dataOnly and --schemaOnly weren't simultaneously specified
487+ if args .schemaOnly and args .dataOnly :
488+ logging .info ("Options --schemaOnly and --dataOnly are mutually exclusive." )
489+ sys .exit (1 )
490+
491+ # instantiate connection
492+ if args .region == LOCAL_REGION :
493+ conn = DynamoDBConnection (aws_access_key_id = args .accessKey , aws_secret_access_key = args .secretKey ,
494+ host = args .host ,
495+ port = int (args .port ), is_secure = False )
496+ sleep_interval = LOCAL_SLEEP_INTERVAL
501497 else :
502- conn = boto .dynamodb2 .connect_to_region (args .region , profile_name = args .profile )
503- sleep_interval = AWS_SLEEP_INTERVAL
504-
505-
506- # don't proceed if connection is not established
507- if not conn :
508- logging .info ('Unable to establish connection with dynamodb' )
509- sys .exit (1 )
510-
511-
512- # set prefix separator
513- prefix_separator = DEFAULT_PREFIX_SEPARATOR
514- if args .prefixSeparator is not None :
515- prefix_separator = args .prefixSeparator
516- if args .noSeparator is True :
517- prefix_separator = None
518-
519- # do backup/restore
520- start_time = datetime .datetime .now ().replace (microsecond = 0 )
521- if args .mode == "backup" :
522- if args .srcTable .find ("*" ) != - 1 :
523- matching_backup_tables = get_table_name_matches (conn , args .srcTable , prefix_separator )
524- logging .info ("Found " + str (len (matching_backup_tables )) + " table(s) in DynamoDB host to backup: " + ", " .join (
525- matching_backup_tables ))
526-
527- threads = []
528- for table_name in matching_backup_tables :
529- t = threading .Thread (target = do_backup , args = (conn , table_name , args .readCapacity ,))
530- threads .append (t )
531- t .start ()
532- time .sleep (THREAD_START_DELAY )
533-
534- for thread in threads :
535- thread .join ()
536-
537- logging .info ("Backup of table(s) " + args .srcTable + " completed!" )
538- else :
539- do_backup (conn , args .srcTable , args .readCapacity )
540- elif args .mode == "restore" :
541- if args .destTable is not None :
542- dest_table = args .destTable
543- else :
544- dest_table = args .srcTable
545-
546- if dest_table .find ("*" ) != - 1 :
547- matching_destination_tables = get_table_name_matches (conn , dest_table , prefix_separator )
548- delete_str = ": " if args .dataOnly else " to be deleted: "
549- logging .info (
550- "Found " + str (len (matching_destination_tables )) + " table(s) in DynamoDB host" + delete_str + ", " .join (
551- matching_destination_tables ))
552-
553- threads = []
554- for table_name in matching_destination_tables :
555- t = threading .Thread (target = delete_table , args = (conn , sleep_interval , table_name ,))
556- threads .append (t )
557- t .start ()
558- time .sleep (THREAD_START_DELAY )
559-
560- for thread in threads :
561- thread .join ()
562-
563- matching_restore_tables = get_restore_table_matches (args .srcTable , prefix_separator )
564- logging .info (
565- "Found " + str (len (matching_restore_tables )) + " table(s) in " + args .dumpPath + " to restore: " + ", " .join (
566- matching_restore_tables ))
567-
568- threads = []
569- for source_table in matching_restore_tables :
570- if args .srcTable == "*" :
571- t = threading .Thread (target = do_restore ,
572- args = (conn , sleep_interval , source_table , source_table , args .writeCapacity ))
573- else :
574- t = threading .Thread (target = do_restore , args = (conn , sleep_interval , source_table ,
575- change_prefix (source_table , args .srcTable , dest_table ,
576- prefix_separator ), args .writeCapacity ,))
577- threads .append (t )
578- t .start ()
579- time .sleep (THREAD_START_DELAY )
498+ if not args .profile :
499+ conn = boto .dynamodb2 .connect_to_region (args .region , aws_access_key_id = args .accessKey ,
500+ aws_secret_access_key = args .secretKey )
501+ sleep_interval = AWS_SLEEP_INTERVAL
502+ else :
503+ conn = boto .dynamodb2 .connect_to_region (args .region , profile_name = args .profile )
504+ sleep_interval = AWS_SLEEP_INTERVAL
505+
506+ # don't proceed if connection is not established
507+ if not conn :
508+ logging .info ('Unable to establish connection with dynamodb' )
509+ sys .exit (1 )
510+
511+ # set prefix separator
512+ prefix_separator = DEFAULT_PREFIX_SEPARATOR
513+ if args .prefixSeparator is not None :
514+ prefix_separator = args .prefixSeparator
515+ if args .noSeparator is True :
516+ prefix_separator = None
517+
518+ # do backup/restore
519+ start_time = datetime .datetime .now ().replace (microsecond = 0 )
520+ if args .mode == "backup" :
521+ if args .srcTable .find ("*" ) != - 1 :
522+ matching_backup_tables = get_table_name_matches (conn , args .srcTable , prefix_separator )
523+ logging .info (
524+ "Found " + str (len (matching_backup_tables )) + " table(s) in DynamoDB host to backup: " + ", " .join (
525+ matching_backup_tables ))
526+
527+ threads = []
528+ for table_name in matching_backup_tables :
529+ t = threading .Thread (target = do_backup , args = (conn , table_name , args .readCapacity ,))
530+ threads .append (t )
531+ t .start ()
532+ time .sleep (THREAD_START_DELAY )
533+
534+ for thread in threads :
535+ thread .join ()
536+
537+ logging .info ("Backup of table(s) " + args .srcTable + " completed!" )
538+ else :
539+ do_backup (conn , args .srcTable , args .readCapacity )
540+ elif args .mode == "restore" :
541+ if args .destTable is not None :
542+ dest_table = args .destTable
543+ else :
544+ dest_table = args .srcTable
545+
546+ if dest_table .find ("*" ) != - 1 :
547+ matching_destination_tables = get_table_name_matches (conn , dest_table , prefix_separator )
548+ delete_str = ": " if args .dataOnly else " to be deleted: "
549+ logging .info (
550+ "Found " + str (
551+ len (matching_destination_tables )) + " table(s) in DynamoDB host" + delete_str + ", " .join (
552+ matching_destination_tables ))
553+
554+ threads = []
555+ for table_name in matching_destination_tables :
556+ t = threading .Thread (target = delete_table , args = (conn , sleep_interval , table_name ,))
557+ threads .append (t )
558+ t .start ()
559+ time .sleep (THREAD_START_DELAY )
560+
561+ for thread in threads :
562+ thread .join ()
563+
564+ matching_restore_tables = get_restore_table_matches (args .srcTable , prefix_separator )
565+ logging .info (
566+ "Found " + str (
567+ len (matching_restore_tables )) + " table(s) in " + args .dumpPath + " to restore: " + ", " .join (
568+ matching_restore_tables ))
569+
570+ threads = []
571+ for source_table in matching_restore_tables :
572+ if args .srcTable == "*" :
573+ t = threading .Thread (target = do_restore ,
574+ args = (conn , sleep_interval , source_table , source_table , args .writeCapacity ))
575+ else :
576+ t = threading .Thread (target = do_restore , args = (conn , sleep_interval , source_table ,
577+ change_prefix (source_table , args .srcTable , dest_table ,
578+ prefix_separator ), args .writeCapacity ,))
579+ threads .append (t )
580+ t .start ()
581+ time .sleep (THREAD_START_DELAY )
580582
581- for thread in threads :
582- thread .join ()
583+ for thread in threads :
584+ thread .join ()
583585
584- logging .info ("Restore of table(s) " + args .srcTable + " to " + dest_table + " completed!" )
585- else :
586- delete_table (conn , sleep_interval , dest_table )
587- do_restore (conn , sleep_interval , args .srcTable , dest_table , args .writeCapacity )
588- elif args .mode == "empty" :
589- if args .srcTable .find ("*" ) != - 1 :
590- matching_backup_tables = get_table_name_matches (conn , args .srcTable , prefix_separator )
591- logging .info ("Found " + str (len (matching_backup_tables )) + " table(s) in DynamoDB host to empty: " + ", " .join (
592- matching_backup_tables ))
593-
594- threads = []
595- for table_name in matching_backup_tables :
596- t = threading .Thread (target = do_empty , args = (conn , table_name ))
597- threads .append (t )
598- t .start ()
599- time .sleep (THREAD_START_DELAY )
600-
601- for thread in threads :
602- thread .join ()
603-
604- logging .info ("Empty of table(s) " + args .srcTable + " completed!" )
605- else :
606- do_empty (conn , args .srcTable )
586+ logging .info ("Restore of table(s) " + args .srcTable + " to " + dest_table + " completed!" )
587+ else :
588+ delete_table (conn , sleep_interval , dest_table )
589+ do_restore (conn , sleep_interval , args .srcTable , dest_table , args .writeCapacity )
590+ elif args .mode == "empty" :
591+ if args .srcTable .find ("*" ) != - 1 :
592+ matching_backup_tables = get_table_name_matches (conn , args .srcTable , prefix_separator )
593+ logging .info (
594+ "Found " + str (len (matching_backup_tables )) + " table(s) in DynamoDB host to empty: " + ", " .join (
595+ matching_backup_tables ))
596+
597+ threads = []
598+ for table_name in matching_backup_tables :
599+ t = threading .Thread (target = do_empty , args = (conn , table_name ))
600+ threads .append (t )
601+ t .start ()
602+ time .sleep (THREAD_START_DELAY )
603+
604+ for thread in threads :
605+ thread .join ()
606+
607+ logging .info ("Empty of table(s) " + args .srcTable + " completed!" )
608+ else :
609+ do_empty (conn , args .srcTable )
610+
611+
612+ if __name__ == "__main__" :
613+ main ()
0 commit comments