GNU/Linux >> Linux の 問題 >  >> Linux

AWSでPythonを使用して1つのDynamoDBから別のDynamoDBテーブルにアイテムをコピーする方法

Pythonを使用して、あるDynamoDBテーブルから別のテーブルにアイテムをコピーできます。同じスクリプトを使用して、異なるアカウントのDynamoDBテーブル間でアイテムをコピーできます。この記事を進める前に、Pythonの基本的な知識があることを前提としています。自分で何かを書く必要はありません。コピー操作を完了するには、スクリプトを実行するだけです。スクリプトとそれに記述されているコードを理解する必要がある場合は、Pythonの基本を理解している必要があります。

このスクリプトは、インターネットとPythonがインストールされている任意のマシンから実行できます。システムにPythonとBoto3をインストールする必要があります。このスクリプトはPython2.7.16でテストされており、Python2.7で利用可能なさまざまなバージョンで試すことができます。

AWSデータパイプラインサービスを使用して、あるDynamoDBテーブルから別のテーブルにアイテムをコピーすることもできますが、これは少し面倒なプロセスです。そこで、タスクを簡素化するために、このスクリプトを自分で作成しました。

では、始めましょう。

前提条件

  1. Pythonの基本的な理解。
  2. LinuxServerにインストールされているPython2.7.16とBoto3。
  3. AWSアカウント(アカウントがない場合は作成します)。
  4. DynamoDBに対する十分な/完全なアクセス許可を持つAWSIAMユーザーの「access_key」と「secret_key」。 (AWSで「access_key」と「secret_key」を使用してIAMユーザーを作成する方法については、ここをクリックしてください)

何をしますか

  1. 前提条件を確認してください。
  2. スクリプトを作成します。
  3. スクリプトを実行します。

前提条件を確認する

Pythonを確認

python --version

ピップを確認

pip --version

Boto3を確認

pip show boto3

スクリプトを作成する

ローカルシステムに次のコードを使用して新しいファイルを作成します。このコードは、私のGithubリポジトリでも入手できます。以下は、Githubのコードへのリンクです。

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

ファイル: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")

構文:

python copy-dynamodb-table.py -sa -ss -da -ds -st -dt

スクリプトを実行します。

上記の構文を参照して、引数をスクリプトに渡すことができます。

コマンド:

python copy-dynamodb-table.py -sa AKI12345IA5XJXFLMTQR -ss ihiHd8 + NzLJ567890z4i6EwcN6hbV2A5cMfurscg -da AKI12345IA5XJXFLMTQR -ds ihiHd8 + NzLJ567890z4

ここ、

  • -sa=ソースAWSアカウントアクセスキー=AKIAQ6GAIA5XJXFLMTQR
  • -ss=ソースAWSアカウントシークレットキー=ihiHd8+ NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
  • -da=宛先AWSアカウントアクセスキー=AKIAQ6GAIA5XJXFLMTQR
  • -ds=宛先AWSアカウントシークレットキー=ihiHd8+ NzLJK5DFfTz4i6EwcN6hbV2A5cMfurscg
  • -st=ソーステーブル=my-source-table
  • -dt=宛先テーブル=my-destination-table

キーを使用する必要があります。ここのキーは私のものです。

スクリプトは4つの異なるユースケースをカバーしています

  1. ユースケース1:ソースと宛先の両方のテーブルが存在しません。
  2. ユースケース2:ソーステーブルは存在しませんが、宛先テーブルは存在します。
  3. ユースケース3:ソーステーブルは存在しますが、宛先テーブルは存在しません。
  4. ユースケース4:ソースと宛先の両方のテーブルが存在します。

これらのユースケースを1つずつ見ていきましょう。

ユースケース1:ソースと宛先の両方のテーブルが存在しません。

アカウントにDynamoDBテーブルがなくてもスクリプトを実行しようとすると、スクリプトは「両方のテーブルが存在しません」というメッセージで終了します。

ユースケース2:ソーステーブルは存在しませんが、宛先テーブルは存在します。

ソーステーブルとして存在しないテーブルを渡そうとすると、スクリプトは「ソーステーブルが存在しません」というメッセージで終了します。

ユースケース3:ソーステーブルは存在しますが、宛先テーブルは存在しません。

上記の2つのユースケースの両方で、操作は実行されません。これで、存在するが宛先テーブルが存在しないソーステーブルを渡すと、スクリプトは宛先テーブルとして指定した名前のテーブルを作成し、ソーステーブルから新しく作成された宛先テーブルにアイテムをコピーします。

>

ユースケース4:ソースと宛先の両方のテーブルが存在します。

このシナリオでは、ソーステーブルからアイテムをコピーする前に宛先テーブルのバックアップが作成され、宛先テーブルが削除されます。テーブルが削除された後、宛先パラメーターで指定した名前の新しいテーブルが作成され、ソーステーブルのアイテムが新しく作成された宛先テーブルにコピーされます。

結論

この記事では、あるDynamoDBテーブルから別のDynamoDBテーブルにアイテムをコピーするPythonスクリプトを見ました。このスクリプトは、あるテーブルから別のテーブルにアイテムをコピーするときに発生する可能性のある4つの異なるユースケースをカバーしています。このスクリプトを使用して、同じまたは異なるAWSアカウントのあるDynamoDBテーブルから別のテーブルにアイテムをコピーできるようになりました。


Linux
  1. Linuxで特定の種類のファイルを検索してあるディレクトリから別のディレクトリにコピーする方法

  2. Pythonスクリプトを使用してSFTPサーバーからファイルをダウンロードする方法

  3. 最後のN行をあるファイルから別のファイルにコピーしますか?

  1. ある mysql データベースから別の mysql データベースにテーブルをコピーする方法

  2. あるディレクトリから別のディレクトリに最新の上位 10 個のファイルをコピーする方法は?

  3. あるマシンから別のマシンにポートを転送する方法は?

  1. Linuxでパーミッションをあるファイルから別のファイルにコピーまたは複製する方法

  2. あるマシンから別のマシンに設定をコピーする方法は?

  3. pidを使用してPythonからプロセスを終了するには?