Puoi usare Python per copiare elementi da una tabella DynamoDB a un'altra. Lo stesso script può essere utilizzato per copiare elementi tra tabelle DynamoDB in account diversi. Prima di procedere con questo articolo, si presume che tu abbia una conoscenza di base di Python. Non è necessario scrivere nulla da soli, è sufficiente eseguire lo script per completare l'operazione di copia. Se hai bisogno di comprendere lo script e il codice in esso scritto, devi avere una conoscenza di base di Python.
Puoi eseguire questo script da qualsiasi macchina con accesso a Internet e Python installato al suo interno. Devi avere Python e Boto3 installati sul tuo sistema. Questo script è stato testato con Python 2.7.16, puoi provare con diverse versioni disponibili in Python 2.7.
Il servizio AWS Data Pipeline può essere utilizzato anche per copiare elementi da una tabella DynamoDB a un'altra, ma è un processo un po' noioso. Quindi, ho scritto questo script da solo per semplificare il compito.
Ora iniziamo.
Prerequisiti
- Conoscenza di base di Python.
- Python 2.7.16 e Boto3 installati sul server Linux.
- Account AWS (crea se non ne hai uno).
- 'access_key' &'secret_key' di un utente AWS IAM con autorizzazioni sufficienti/complete su DynamoDB. (Fai clic qui per imparare a creare un utente IAM con 'access_key' &'secret_key' su AWS, )
Cosa faremo
- Verifica i prerequisiti.
- Crea uno script.
- Esegui lo script.
Verifica prerequisiti
Controlla Python
python --versione
Seleziona Pip
pip --versione
Seleziona Boto3
pip mostra boto3
Crea uno script
Crea un nuovo file con il seguente codice sul tuo sistema locale. Il codice è disponibile anche sul mio Github Repo. Quello che segue è il link al codice su Github.
Link Github: https://github.com/shivalkarrahul/DevOps/blob/master/aws/python/aws-copy-dynamo-db-table/copy-dynamodb-table.py
File: copy-dynamodb-table.py
import boto3 import os import sys import argparse import datetime global args parser = argparse.ArgumentParser() parser.add_argument('-sa', '--source_aws_access_key_id', required=True, action="store", dest="source_aws_access_key_id", help="Source AWS Account aws_access_key_id", default=None) parser.add_argument('-ss', '--source_aws_secret_access_key', required=True, action="store", dest="source_aws_secret_access_key", help="Source AWS Account aws_secret_access_key", default=None) parser.add_argument('-da', '--destination_aws_access_key_id', required=True, action="store", dest="destination_aws_access_key_id", help="Destination AWS Account aws_access_key_id", default=None) parser.add_argument('-ds', '--destination_aws_secret_access_key', required=True, action="store", dest="destination_aws_secret_access_key", help="Destination AWS Account aws_secret_access_key", default=None) parser.add_argument('-st', '--sourceTableName', required=True, action="store", dest="sourceTableName", help="Source AWS Account DyanamoDB Table", default=None) parser.add_argument('-dt', '--destinationTableName', required=True, action="store", dest="destinationTableName", help="Destination AWS Account DyanamoDB Table", default=None) args = parser.parse_args() source_aws_access_key_id = args.source_aws_access_key_id source_aws_secret_access_key = args.source_aws_secret_access_key destination_aws_access_key_id = args.destination_aws_access_key_id destination_aws_secret_access_key = args.destination_aws_secret_access_key sourceTableName=args.sourceTableName destinationTableName=args.destinationTableName sourceTableExists = "false" destinationTableExists = "false" print("Printing values") print("source_aws_access_key_id", source_aws_access_key_id) print("source_aws_secret_access_key", source_aws_secret_access_key) print("destination_aws_access_key_id", destination_aws_access_key_id) print("destination_aws_secret_access_key", destination_aws_secret_access_key) print("sourceTableName", sourceTableName) print("destinationTableName", destinationTableName) timeStamp = datetime.datetime.now() backupName = destinationTableName + str(timeStamp.strftime("-%Y_%m_%d_%H_%M_%S")) item_count = 1000 #Specify total number of items to be copied here, this helps when a specified number of items need to be copied counter = 1 # Don't not change this source_session = boto3.Session(region_name='eu-west-3', aws_access_key_id=source_aws_access_key_id, aws_secret_access_key=source_aws_secret_access_key) source_dynamo_client = source_session.client('dynamodb') target_session = boto3.Session(region_name='eu-west-3', aws_access_key_id=destination_aws_access_key_id, aws_secret_access_key=destination_aws_secret_access_key) target_dynamodb = target_session.resource('dynamodb') dynamoclient = boto3.client('dynamodb', region_name='eu-west-3', #Specify the region here aws_access_key_id=source_aws_access_key_id, #Add you source account's access key here aws_secret_access_key=source_aws_secret_access_key) #Add you source account's secret key here dynamotargetclient = boto3.client('dynamodb', region_name='eu-west-3', #Specify the region here aws_access_key_id=destination_aws_access_key_id, #Add you destination account's access key here aws_secret_access_key=destination_aws_secret_access_key) #Add you destination account's secret key here # response = dynamotargetclient.list_tables() # print("List of tables", response) dynamopaginator = dynamoclient.get_paginator('scan') def validateTables(sourceTable, destinationTable): print("Inside validateTables") try: dynamoclient.describe_table(TableName=sourceTable) sourceTableExists = "true" except dynamotargetclient.exceptions.ResourceNotFoundException: sourceTableExists = "false" try: dynamotargetclient.describe_table(TableName=destinationTable) destinationTableExists = "true" except dynamotargetclient.exceptions.ResourceNotFoundException: destinationTableExists = "false" return {'sourceTableExists': sourceTableExists, 'destinationTableExists':destinationTableExists} def copyTable(sourceTable, destinationTable,item_count,counter): print("Inside copyTable") print("Coping", sourceTable, "to", destinationTable) print('Start Reading the Source Table') try: dynamoresponse = dynamopaginator.paginate( TableName=sourceTable, Select='ALL_ATTRIBUTES', ReturnConsumedCapacity='NONE', ConsistentRead=True ) except dynamotargetclient.exceptions.ResourceNotFoundException: print("Table does not exist") print("Exiting") sys.exit() print('Finished Reading the Table') print('Proceed with writing to the Destination Table') print("Writing first", item_count , "items" ) print(dynamoresponse) for page in dynamoresponse: for item in page['Items']: if (counter == item_count): print("exiting") sys.exit() else: print('writing item no', counter) dynamotargetclient.put_item( TableName=destinationTable, Item=item ) counter = counter + 1 def backupTable(destTableName, backupTimeStamp): print("Inside backupTable") print("Taking backup of = ", destTableName) print("Backup Name = ", backupTimeStamp) response = dynamotargetclient.create_backup( TableName=destTableName, BackupName=backupTimeStamp ) print("Backup ARN =", response["BackupDetails"]["BackupArn"]) def deleteDestinationTable(destTableName): print("Inside deleteDestinationTable") try: dynamotargetclient.delete_table(TableName=destTableName) waiter = dynamotargetclient.get_waiter('table_not_exists') waiter.wait(TableName=destTableName) print("Table deleted") except dynamotargetclient.exceptions.ResourceNotFoundException: print("Table does not exist") def doesNotExist(): print("Inside doesNotExist") print("Destination table does not exist ") print("Exiting the execution") # sys.exit() def createDestinationTable(sourceTable): print("Inside createDestinationTable") source_table = source_session.resource('dynamodb').Table(sourceTable) target_table = target_dynamodb.create_table( TableName=destinationTableName, KeySchema=source_table.key_schema, AttributeDefinitions=source_table.attribute_definitions, ProvisionedThroughput={ 'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5 }) target_table.wait_until_exists() target_table.reload() result = validateTables(sourceTableName, destinationTableName) print("value of sourceTableExists = ", result['sourceTableExists']) print("value of destinationTableExists = ", result['destinationTableExists']) if (result['sourceTableExists'] == "false" ) and (result['destinationTableExists'] == "false" ): print("Both the tables do not exist") elif (result['sourceTableExists'] == "false" ) and (result['destinationTableExists'] == "true" ): print("Source Table does not exist") elif (result['sourceTableExists'] == "true" ) and (result['destinationTableExists'] == "false" ): createDestinationTable(sourceTableName) copyTable(sourceTableName, destinationTableName, item_count, counter) elif (result['sourceTableExists'] == "true" ) and (result['destinationTableExists'] == "true" ): backupTable(destinationTableName, backupName) deleteDestinationTable(destinationTableName) createDestinationTable(sourceTableName) copyTable(sourceTableName, destinationTableName, item_count, counter) else: print("Something is wrong")
Sintassi:
python copy-dynamodb-table.py -sa
Esegui lo script.
Puoi fare riferimento alla sintassi sopra e passare gli argomenti allo script.
Comando:
python copy-dynamodb-table.py -sa AKI12345IA5XJXFLMTQR -ss ihiHd8 + NzLJ567890z4i6EwcN6hbV2A5cMfurscg -da AKI12345IA5XJXFLMTQR -ds ihiHd8 + NzLJ567890z4i6EwcN6hbV2A5cMfurscg -st my-fonte-tavolo -dt my-destinazione-tabella
Qui,
- -sa =Chiave di accesso all'account AWS di origine = AKIAQ6GAIA5XJXFLMTQR
- -ss = Chiave segreta dell'account AWS di origine = ihiHd8+NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
- -da = Destinazione Chiave di accesso all'account AWS = AKIAQ6GAIA5XJXFLMTQR
- -ds = Chiave segreta dell'account AWS di destinazione = ihiHd8+NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
- -st = Tabella di origine = la mia-tabella-origine
- -dt = Tabella di destinazione = tabella-mia-destinazione
Devi usare le tue chiavi, le chiavi qui appartengono a me.
Lo script copre 4 diversi casi d'uso
- Caso d'uso 1:entrambe le tabelle, Source e Destination, non esistono.
- Caso d'uso 2: la tabella di origine non esiste ma esiste la tabella di destinazione.
- Caso d'uso 3: la tabella di origine esiste ma la tabella di destinazione non esiste.
- Caso d'uso 4:esistono entrambe le tabelle, Sorgente e Destinazione.
Vediamo questi casi d'uso uno per uno.
Caso d'uso 1:entrambe le tabelle, Source e Destination, non esistono.
Se non hai tabelle DynamoDB nel tuo account e tenti comunque di eseguire lo script, lo script uscirà con il messaggio "Entrambe le tabelle non esistono".
Caso d'uso 2: la tabella di origine non esiste ma la tabella di destinazione esiste.
Se provi a passare la tabella che non esiste come tabella di origine, lo script uscirà con il messaggio "La tabella di origine non esiste".
Caso d'uso 3: la tabella di origine esiste ma la tabella di destinazione non esiste.
In entrambi i casi d'uso precedenti, non viene eseguita alcuna operazione. Ora, se passi la tabella di origine che esiste ma la tabella di destinazione non esiste, lo script creerà una tabella con il nome che specifichi come tabella di destinazione e copia gli elementi dalla tabella di origine alla tabella di destinazione appena creata.
Caso d'uso 4:esistono entrambe le tabelle, Sorgente e Destinazione.
In questo scenario, viene eseguito un backup della tabella di destinazione prima di copiare gli elementi dalla tabella di origine, quindi viene eliminata la tabella di destinazione. Dopo che la tabella è stata eliminata, viene creata una nuova tabella con il nome specificato nel parametro di destinazione e quindi gli elementi dalla tabella di origine vengono copiati nella tabella di destinazione appena creata.
Conclusione
In questo articolo, abbiamo visto lo script Python per copiare elementi da una tabella DynamoDB a un'altra tabella DynamoDB. Lo script copre quattro diversi casi d'uso che possono verificarsi durante la copia di elementi da una tabella all'altra. Ora puoi utilizzare questo script per copiare elementi da una tabella DynamoDB a un'altra nello stesso account AWS o in diversi.