2

So I'm attempting to sync Dynamodb tables using put_item. But I've run into an issue.

Invalid type for parameter Item.Artist, value: No One You Know, type: <class 'str'>, valid types: <class 'dict'>

From reading the documentation it looks like when using put_item it requires a dict so essentially something like this:

'{'Artist': {'S': 'No One You Know'},'SongTitle': {'S': 'Call Me Today'}}'

In order to add it correctly.

Here is my code:

#!/usr/bin/python3
import boto3
source = boto3.resource('dynamodb', 'us-east-1')
dest = boto3.client('dynamodb', 'us-west-2')

def sync(source, dest):
     table = source.Table("myMusic")
     scan_kwargs = {
         'ProjectionExpression': "Artist, SongTitle"
     }
     done = False
     start_key = None
     while not done:
         if start_key:
             scan_kwargs['ExclusiveStartKey'] = start_key
         response = table.scan(**scan_kwargs)
         for item in response['Items']:
             dest.put_item(TableName="myMusic", Item=item)
             #print(item)
         start_key = response.get('LastEvaluatedKey', None)
         done = start_key is None


sync(source, dest)

So if I uncomment the print statement I get:

{'Artist': 'No One You Know', 'SongTitle': 'Call Me Today'}

Is there any way to sanitize the output or add the additional required 'S' or am I going about this the wrong way?

mcgoosh
  • 59
  • 1
  • 2
  • 11

1 Answers1

5

At some stage in your code, you will have item = {'Artist': 'No One You Know', 'SongTitle': 'Call Me Today'} which you are saying is printed when you uncomment the print statement.

Use the following snippet of code:

newItem = { 'Artist': {}, 'SongTitle': {} }

newItem['Artist']['S'] = item['Artist']
newItem['SongTitle']['S'] = item['SongTitle']

So whole code becomes:

#!/usr/bin/python3
import boto3
source = boto3.resource('dynamodb', 'us-east-1')
dest = boto3.client('dynamodb', 'us-west-2')

def sync(source, dest):
     table = source.Table("myMusic")
     scan_kwargs = {
         'ProjectionExpression': "Artist, SongTitle"
     }
     done = False
     start_key = None
     while not done:
         if start_key:
             scan_kwargs['ExclusiveStartKey'] = start_key
         response = table.scan(**scan_kwargs)
         for item in response['Items']:
             
#######################  SNIPPET  #######################  
             newItem = { 'Artist': {}, 'SongTitle': {} }

             newItem['Artist']['S'] = item['Artist']
             newItem['SongTitle']['S'] = item['SongTitle']
#######################  SNIPPET  #######################  

             dest.put_item(TableName="myMusic", Item=newItem)
             #print(item)
         start_key = response.get('LastEvaluatedKey', None)
         done = start_key is None

NetanMangal
  • 309
  • 1
  • 9
  • Thank You! That worked. I wasn't sure if I should be using boto3.resource as the dest as well but that worked very well. I appreciate it. – mcgoosh Apr 27 '21 at 17:07