Kopieren von Elementen aus einer DynamoDB in eine andere DynamoDB-Tabelle mit Python auf AWS

Sie können Python verwenden, um Elemente von einer DynamoDB-Tabelle in eine andere zu kopieren. Dasselbe Skript kann verwendet werden, um Elemente zwischen DynamoDB-Tabellen in verschiedenen Konten zu kopieren. Bevor wir mit diesem Artikel fortfahren, wird vorausgesetzt, dass Sie ein grundlegendes Verständnis von Python haben. Sie müssen nichts selbst schreiben, sondern nur das Skript ausführen, um den Kopiervorgang auszuführen. Wenn Sie das Skript und den darin geschriebenen Code verstehen wollen, müssen Sie ein Grundverständnis von Python haben.

Sie können dieses Skript von jedem Rechner aus ausführen, der Zugang zum Internet hat und auf dem Python installiert ist. Sie müssen Python und Boto3 auf Ihrem System installiert haben. Dieses Skript wurde mit Python 2.7.16 getestet, Sie können es mit anderen Versionen von Python 2.7 ausprobieren.

Der AWS Data Pipeline Service kann auch verwendet werden, um Elemente von einer DynamoDB-Tabelle in eine andere zu kopieren, aber das ist ein etwas mühsamer Prozess. Daher habe ich dieses Skript selbst geschrieben, um diese Aufgabe zu vereinfachen.

Also, fangen wir an.

Vorraussetzungen

  1. Grundlegendes Verständnis von Python.
  2. Python 2.7.16 und Boto3 auf dem Linux-Server installiert.
  3. AWS-Konto(Erstellen Sie es, wenn Sie noch keines haben).
  4. ‚access_key‘ & ’secret_key‘ eines AWS IAM-Benutzers mit ausreichenden/vollständigen Berechtigungen auf DynamoDB. (Klicken Sie hier, um zu erfahren, wie Sie einen IAM-Benutzer mit ‚access_key‘ & ’secret_key‘ auf AWS erstellen, )

Was werden wir tun

  1. Voraussetzungen prüfen.
  2. Erstellen Sie ein Skript.
  3. Ausführen des Skripts.

Vorraussetzungen prüfen

Python prüfen

python –version

Python Version

Pip prüfen

pip –version

Pip-Version

Boto3 prüfen

pip show boto3

Boto3 Version

Ein Skript erstellen

Erstellen Sie eine neue Datei mit dem folgenden Code auf Ihrem lokalen System. Der Code ist auch auf meinem Github Repo verfügbar. Hier der Link zum Code auf Github.

Github-Link:https://github.com/shivalkarrahul/DevOps/blob/master/aws/python/aws-copy-dynamo-db-table/copy-dynamodb-table.py

Datei: 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")

Syntax:

python copy-dynamodb-table.py -sa <Quell-Account-Zugriffsschlüssel-hier> -ss <Quell-Account-Geheimnis-Schlüssel-hier> -da <Ziel-Account-Zugriffsschlüssel-hier> -ds <Ziel-Account-Geheimnis-Schlüssel-hier> -st <Quell-Tabelle-Name-hier> -dt <Ziel-Tabelle-Name-hier>

Führen Sie das Skript aus.

Sie können sich auf die obige Syntax beziehen und die Argumente an das Skript übergeben.

Befehl:

python copy-dynamodb-table.py -sa AKI12345IA5XJXFLMTQR -ss ihiHd8+NzLJ567890z4i6EwcN6hbV2A5cMfurscg -daAKI12345IA5XJXFLMTQR -ds ihiHd8+NzLJ567890z4i6EwcN6hbV2A5cMfurscg -st my-source-table -dt my-destination-table

Hier,

  • -sa =Quelle AWS-Konto Zugangsschlüssel = AKIAQ6GAIA5XJXFLMTQR
  • -ss = Quell-AWS-Konto Geheimschlüssel = ihiHd8+NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
  • -da = Ziel-AWS-Konto Zugangsschlüssel = AKIAQ6GAIA5XJXFLMTQR
  • -ds = Geheimer Schlüssel des AWS-Zielkontos = ihiHd8+NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
  • -st = Quell-Tabelle = my-source-table
  • -dt = Zieltabelle = my-destination-table

Sie müssen Ihre Schlüssel verwenden, die Schlüssel hier gehören mir.

Das Skript deckt 4 verschiedene Use-Cases ab

  1. Anwendungsfall 1: Beide Tabellen, Quelle und Ziel, sind nicht vorhanden.
  2. Anwendungsfall 2: Die Quelltabelle existiert nicht, aber die Zieltabelle existiert.
  3. Anwendungsfall 3: Die Quelltabelle existiert, aber die Zieltabelle existiert nicht.
  4. Anwendungsfall 4: Beide Tabellen, Quelle und Ziel, sind vorhanden.

Schauen wir uns diese Anwendungsfälle nacheinander an.

Anwendungsfall 1: Beide Tabellen, Quelle und Ziel, sind nicht vorhanden.

Wenn Sie keine DynamoDB-Tabellen in Ihrem Konto haben und trotzdem versuchen, das Skript auszuführen, wird das Skript mit der Meldung „Both the tables do not exist“ beendet.

Die beiden Tabellen sind nicht vorhanden

Anwendungsfall 2: Die Quelltabelle existiert nicht, aber die Zieltabelle existiert.

Wenn Sie versuchen, die Tabelle, die nicht existiert, als Quelltabelle zu übergeben, wird das Script mit der Meldung „Quelltabelle existiert nicht“ beendet.

Quelltabelle existiert nicht

Anwendungsfall 3: Quelltabelle existiert, aber die Zieltabelle existiert nicht.

In den beiden obigen Anwendungsfällen wird keine Operation durchgeführt. Wenn Sie nun die Quelltabelle übergeben, die existiert, aber die Zieltabelle nicht existiert, erstellt das Script eine Tabelle mit dem Namen, den Sie als Zieltabelle angeben, und kopiert Elemente aus der Quelltabelle in die neu erstellte Zieltabelle.

Zieltabelle existiert nicht

Anwendungsfall 4: Beide Tabellen, Quelle und Ziel, sind vorhanden.

In diesem Szenario wird vor dem Kopieren von Artikeln aus der Quelltabelle eine Sicherung der Zieltabelle erstellt und anschließend die Zieltabelle gelöscht. Nachdem die Tabelle gelöscht wurde, wird eine neue Tabelle mit dem Namen erstellt, den Sie im Zielparameter angeben, und dann werden die Artikel aus der Quelltabelle in die neu erstellte Zieltabelle kopiert.

Sowohl die Tabellen

Die beiden Tabellen existieren

Sicherung der Zieltabelle vor dem Kopieren neuer Artikel

Fazit

In diesem Artikel haben wir das Python-Skript zum Kopieren von Elementen aus einer DynamoDB-Tabelle in eine andere DynamoDB-Tabelle gesehen. Das Skript deckt vier verschiedene Anwendungsfälle ab, die beim Kopieren von Elementen von einer Tabelle in eine andere auftreten können. Sie können dieses Skript nun verwenden, um Elemente von einer DynamoDB-Tabelle in eine andere im selben oder einem anderen AWS-Konto zu kopieren.

Das könnte dich auch interessieren …