AWS DynamoDBからデータを取り出してJSON形式で出力するPythonのプログラム | そう備忘録

AWS DynamoDBからデータを取り出してJSON形式で出力するPythonのプログラム

DynamoDB

AWS(Amazon Web Services)のDynamoDBからデータを取り出して全件JSON形式て出力するPythonのプログラムを備忘録として記事にしておく。

尚、読み込むDynamoDBは以前に「ラズパイZEROとモーションセンサーで見守りシステムをつくる」の記事で作成したモーションセンサーでのカウント記録が格納されたテーブルとした。

大まかな手順は以下の通り。

  1. AWS IAMでDynamoDBにアクセスできるユーザを作成する
  2. Pythonでプログラムを作成する

関連記事

2020年7月20日追記

IAMでユーザを作成する

AWSのコンソールにログインをしてサービスからIAM(Identity and Access Management)を選択して左のメニューから”アクセス管理”ー>”ユーザ”をクリックする。

ユーザを追加

上部の「ユーザを追加」ボタンをクリックする。

IAMでユーザの追加

ユーザ詳細の設定で、

  • ユーザ名:任意の文字列
  • アクセスの種類:プログラムによるアクセスにチェックする

「次のステップ:アクセス権限」ボタンをクリックする。

ユーザの詳細を設定

アクセス権限

「既存のポリシーを直接アタッチ」を選択して、”AmazonDynamoDBReadOnlyAccess”※にチェックを入れて「次のステップ:確認」ボタンをクリックする。

※今回は参照するだけなのでこの権限でOK

AmazonDynamoDBReadOnlyAccessを追加

管理ポリシーでAmazonDynamoDBReadOnlyAccessが追加されている事を確認して「アクセス権限の追加」ボタンをクリックする。

権限の追加 

タグの追加

必要に応じてタグを追加する。

自分はタグは追加せずに「次のステップ:確認」ボタンをクリックした。

タグは設定していない

ユーザの作成

確認画面が表示されるので「ユーザの作成」ボタンを押すとユーザが作成されてアクセスキーIDとシークレットアクセスキーが表示されるので後でプログラム中で使用するので両方共に控えておく。

アクセスキーとシークレットキー

以上でユーザの作成は終了。

必要なモジュール

PythonアプリケーションからAWSの各種サービスを使うためのAWS SDK for Python (Boto3)をインストールする。

Boto3に関してはこちらのページを参照。

自分はWindows環境にAnacondaでPython環境を構築しているのでAnacondaプロンプトから以下のコマンドでBoto3をインストールした。

pip install boto3

boto3のインストール

プログラム

プログラム実行環境

OS

Windows10 Pro及びHome 64Bit

Python

Ver3.7.7(Anaconda上で実行)

プログラムソースコード

プログラムは以下の通り。

Developers.ioのこちらの記事を参考にしている。

というか中身はそのままで自分の理解の為にコメントを書き加えただけ。

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 29 14:55:27 2020

@author: Souichirou.Kikuchi
"""

import json
from typing import List
from decimal import Decimal

import boto3
from boto3.resources.base import ServiceResource
from boto3.dynamodb.types import Binary

def scan_table(table_name: str, dynamodb: ServiceResource) -> List[dict]:
    table = dynamodb.Table(table_name) # DynamoDBテーブル読み込み
    resp = table.scan() # scan
    table_items = resp['Items']
    while 'LastEvaluatedKey' in resp: # 1回のscanでは取得できる件数に限界があるので繰り返す
        resp = table.scan(
            ExclusiveStartKey=resp['LastEvaluatedKey']
        )
        table_items.extend(resp['Items'])
    return table_items

def default_proc(obj) -> object: # 型変換
    if isinstance(obj, Decimal): # Decimalであればintかfloatに変換
        if int(obj) == obj:
            return int(obj)
        else:
            return float(obj)
    elif isinstance(obj, Binary):
        return obj.value
    elif isinstance(obj, bytes):
        return obj.decode(encoding='default')
    elif isinstance(obj, set):
        return list(obj)
    try:
        return str(obj)
    except Exception:
        return None

def put_data(table_items: List[dict]) -> None:
    with open('./export.json', 'w') as f:
        json.dump(table_items, f, default=default_proc, ensure_ascii=False, sort_keys=True, indent=4)

if __name__ == '__main__':
    table_name = 'Table Name' # DynamoDBのエーブル名
    dynamodb = boto3.resource('dynamodb',
                          aws_access_key_id='XXXXXX', # 控えておいたアクセスキーID
                          aws_secret_access_key='XXXXXX', # 控えておいたシークレットアクセスキー
                          region_name='ap-northeast-1') # リージョン(東京)
    table_items = scan_table(table_name, dynamodb)
    put_data(table_items)

補足説明

16~25行目

DynamoDBをtable.scanで読み込んでいる。

1度scanした後、whileでscanを繰り返しているのは1度のscanで読み取れる件数に限界があるのでデータの最後まで繰り返している。

LastEvaluatedKeyに取得できなかったデータの最初の位置がセットされる。

27~42行目

DynamoDBから取り出した値をそのまま出力しようとするとTypeErrorが発生してしまうので型変換を行っている。

例えば数値(Number型)の項目はDecimal型でと取り出されるのでInt型かfloat型に変換している。

46行目のjson.dumpでの出力時のdefault指定でこの関数を呼び出して型変換を行っている。

46行目

JSON形式で出力する。

ensure_ascii=False:非 ASCII 文字はエスケープせずにそのまま出力する

indent=4:4Byteの空白でインデントする

終わりに

以上でDynamoDBから全件JSON形式でデータを取り出すプログラムの記事は終了。

いずれキー指定で取り出すプログラムも作ってみたい。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。