ablog

不器用で落着きのない技術者のメモ

DynamoDB に BatchWriteItem で書こうとすると "when calling the BatchWriteItem operation: The provided key element does not match the schema" と怒られる。

事象

DynamoDB に BatchWriteItem で書こうとすると "when calling the BatchWriteItem operation: The provided key element does not match the schema" と怒られる。

Error executing batch_writer
Traceback (most recent call last):
  File "./ddb_csv_importer.py", line 35, in write_to_dynamo
    exit
  File "/home/ec2-user/.pyenv/versions/3.6.9/lib/python3.6/site-packages/boto3/dynamodb/table.py", line 156, in __exit__
    self._flush()
  File "/home/ec2-user/.pyenv/versions/3.6.9/lib/python3.6/site-packages/boto3/dynamodb/table.py", line 137, in _flush
    RequestItems={self._table_name: items_to_send})
  File "/home/ec2-user/.pyenv/versions/3.6.9/lib/python3.6/site-packages/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/ec2-user/.pyenv/versions/3.6.9/lib/python3.6/site-packages/botocore/client.py", line 635, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the BatchWriteItem operation: The provided key element does not match the schema

対策

型を DynamoDB のテーブル定義の String に変換すると解消した。

  • 修正前
            batch.put_item(
               Item={
                  "col1" : i,
                  "col2" : i
               }
            )
  • 修正後
            batch.put_item(
               Item={
                  "col1" : str(i),
                  "col2" : str(i)
               }
            )

補足

  • 周辺のコード
def write_to_dynamo(rows):
   try:
      table = dynamodb.Table(tableName)
   except:
      print("Error loading DynamoDB table. Check if table was created correctly and environment variable.")

   try:
      with table.batch_writer() as batch:
         for i in range(len(rows)):
            od = rows[i]
            l = list(od.items())
            batch.put_item(
               Item={
                  "col1" : str(i),
                  "col2" : str(i)
               }
            )
  • テーブル定義
$ aws dynamodb describe-table --table-name testTable
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "col1",
                "AttributeType": "S"
            },
            {
                "AttributeName": "col2",
                "AttributeType": "S"
            }
        ],
        "TableName": "testTable",
        "KeySchema": [
            {
                "AttributeName": "col1",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "col2",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1608254891.316,
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/testTable",
        "TableId": "40c2****-****-****-****-********39cd"
    }
}