LoginSignup
1
1

More than 5 years have passed since last update.

DynamoDBのデータ型を取り除く(Python3版)

Last updated at Posted at 2018-06-06

はじめに

DynamoDBから値を取得するときに、batch_get_itemの戻り値やDynamoDB Streamのイベントに格納されるデータの形式が、次のようにデータ型を含んだ形になっていて、そのままでは扱いづらくなっています。

{
    'userId': {
        'N': '12345'
    },
    'userName': {
        'S': 'ユーザ1'
    },
    'mailAddresses': {
        'L': [
            {
                'S': 'hoge@example.com'
            },
            {
                'S': 'fuga@example.com'
            }
        ]
    }
}

数値も文字列になってしまっています。
この形式のデータを

{
    'userId': 12345,
    'userName': 'ユーザ1',
    'mailAddresses': [
        'hoge@example.com',
        'fuga@example.com'
    ]
}

に直すコードが欲しかったので、書いてみました。

コード

remove_data_type の引数に、データ型を含むdictを渡すと、データ型に従って変換されたdictが返ります。
データ型毎に処理を書いているだけです。
一部、再帰が入っています。

import base64

def remove_data_type(record):
    return {k: remove_one_data_type(record[k]) for k in record}

def remove_one_data_type(data_type_and_value_dict):
    data_type, value = list(data_type_and_value_dict.items())[0]

    if data_type == 'S' or data_type == 'BOOL':
        return value

    if data_type == 'N':
        return float(value) if '.' in value else int(value)

    if data_type == 'B':
        return base64.b64decode(value)

    if data_type == 'NS':
        return set([float(v) if '.' in v else int(v) for v in value])

    if data_type == 'SS':
        return set(value)

    if data_type == 'BS':
        return set([base64.b64decode(v) for v in value])

    if data_type == 'M':
        return remove_data_type(value)

    if data_type == 'L':
        return [remove_one_data_type(v) for v in value]

    if data_type == 'NULL':
        return None

    raise Exception('Invalid data type: ' + data_type)

次のように呼び出します。

dynamodb_record = {
    'userId': {
        'N': '12345'
    },
    'userName': {
        'S': 'ユーザ1'
    },
    'mailAddresses': {
        'L': [
            {
                'S': 'hoge@example.com'
            },
            {
                'S': 'fuga@example.com'
            }
        ]
    }
}

converted_record = remove_data_type(dynamodb_record)
print(converted_record)
出力
{
    'userId': 12345,
    'userName': 'ユーザ1',
    'mailAddresses': [
        'hoge@example.com',
        'fuga@example.com'
    ]
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1