概要

ソースを読んでいた時に、「import Boto3」という記述が出てきて、「なんだこれは?」と気になって調べてみた。習うより慣れろの精神で、とりあえず触ってみたのでそれをまとめた。

Boto3とは

  • 一言で言うと「pythonからAWSリソースを操作するためのライブラリ」
    AWS SDK for Pythonの別称。
  • SDK=SoftwareDevelopmentKitsの略
  • AWSサービスを操作する方法は以下の3つの方法がある、と整理できる
    • AWS SDK=AWSサービスをプログラムから操作するためのもの
    • AWS CLI =AWSサービスをCUIで(ターミナル上から)操作するためのもの
    • マネジメントコンソール=AWSサービスをGUIで(ブラウザから)操作するためのもの

実際にBoto3使ってみた(DynamoDBを例に)

いろんなAWSサービスがあるが、 DynamoDBに触れたことがなかったので仕組みの勉強も兼ねて、Boto3からDynamoDBを操作し、簡単なテーブルのCRUD操作を行ってみた。
その際の手順を下記に整理した。

<事前準備>

  • IAMユーザの作成、認証情報の設定=(アクセスキー・シークレットアクセスキーの生成・セット)→これもSDKでできるようだが本記事では割愛する

※アクセスキー/シークレットアクセスキーに関しては aws configureコマンドで設定した

<前提>
resourceAPIとclientAPIの2種類があるが、今回はresourceAPIを使用している
(2種類の違いについては後述)

<操作手順>
①Boto3のインポート、リソースのインスタンスの取得

# test.py
import boto3
dynamodb = boto3.resource('dynamodb')

②テーブル作成
下記のようなテーブルを作成してみる

BookId Title Release_Year
001 リーダブルコード 2012
002 スッキリわかるSQL入門 2018
003 すっきりわかるPython入門 2019
004 メモの魔力 2018
  • create_tableメソッドを使用
  • パーティションキー・ソートキー・文字型の指定
  • LSI/GSI(ローカル(グローバル)セカンダリインデックス)の指定などもできる(が今回は割愛)
    ※パーティションキー:データをどのパーティションに配置するか決定する
    ※ソートキー:パーティションキーと組み合わせてデータを一意に絞り込む
    ※LSI:元のテーブルにおけるパーティションキーはそのままで、異なるソートキーを指定し新しいテーブルを作成できる仕組み
    ※GSI:元のテーブルで設定されたものとは違うパーティションキーとソートキーを指定し、新しいテーブルを作成できる仕組み
def create_books_table():
    table = dynamodb.create_table(
        TableName='Books',   #テーブル名
        KeySchema=[
            {
                'AttributeName': 'BookId', #←Key名
                'KeyType': 'HASH' #パーティションキー
            },
            {
                'AttributeName': 'Title',
                'KeyType': 'RANGE'#ソートキー
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'BookId',
                'AttributeType': 'S' #文字型の選択(S(string)/N(Number)/B(Binary))
            },
            {
                'AttributeName': 'Title',
                'AttributeType': 'S'
            },
        ],
        # オンデマンドキャパシティモードによる課金
        BillingMode='PAY_PER_REQUEST'
        # プロビジョニング済みキャパシティモードにする場合は下記のように書く
        # ProvisionedThroughput={
        #    'ReadCapacityUnits': 1,
        #    'WriteCapacityUnits': 1
        # }
    )
    return table
if __name__ == '__main__': #このファイルが直接実行された時だけ以下の処理を行う
    print('Creat table...')
    table = create_books_table() #Booksテーブルを作成する
    table.wait_until_exists() #テーブルが存在する(作成される)まで待つ
    print('Created!')
    print('Table status:', table.table_status) #テーブルの作成ステータスを表示
    print('Item count:', table.item_count) #テーブルのアイテム数を表示

③テーブルへのデータ追加

  • put_itemメソッドを使用
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Books')
table.put_item(Item={'001': 'リーダブルコード'})
table.put_item(Item={'002': 'スッキリわかるSQL入門'})
table.put_item(Item={'003': 'スッキリわかるPython入門'})
table.put_item(Item={'004': 'メモの魔力'})

④テーブルからデータを取得
<一件取得の場合→get_itemメソッドを使用>
メソッドの戻り値のItemプロパティに取得結果が辞書形式で入っている

<br /># Books テーブルから指定したプライマリキーに一致するアイテムを取得
table = boto3.resource("dynamodb").Table("Books")
response = table.get_item(Key={"BookId": "001"})

# 取得結果を表示
if "Item" in response:
    item = response["Item"] 
    print(item["title"], item["Release_Year"])
else:
    print("Not found")

<件数を指定して取得の場合→table.scanメソッドを使用し、Limitで件数を指定>
メソッドの戻り値のItemプロパティに取得結果が辞書形式で入っている

# Books テーブルから3件のアイテムを取得
table = boto3.resource('dynamodb').Table('Books')
response = table.scan(Limit=3, ReturnConsumedCapacity='TOTAL')

# スキャン結果の表示
items = response['Items']
print('Scanned items: %d' % len(items))
for item in items:
    print(item['Title'], item['Release_Year'])

⑤テーブルのデータ削除

  • delete_itemメソッドを使用
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Books')
table.delete_item(Key={'004': 'メモの魔力'})

⑥テーブルごと削除

  • table.deleteメソッドを使用
# Books テーブルを参照
dynamodb = boto3.resource('dynamodb').Table('Books')
# Books テーブルを削除する
table.delete()

resource APIとclient APIについて

  • resourceAPI

AWSのリソースをオブジェクト指向で扱えるようになっているAPI
=対象のリソースをオブジェクトとして取得してから、オブジェクトの持つプロパティを参照して情報を取得する
※サービスによってはresourceAPIが用意されていない場合もある。その際はclient APIを使用する必要がある。

  • clientAPI

AWSのREST APIと1対1で対応したAPI
→対象のリソースのリソースIDを引数に与えてメソッドを実行
→実行結果は辞書型で返ってくるので、必要な情報を取得するためのキーを指定して取得する
※場合によっては必要な情報を取り出すのが面倒な場合がある(辞書が入れ子になっている場合もあるので)

上記を踏まえると、resource APIとclient API を状況によって使い分ける必要がありそう。

最後に(触ってみた感想など)

SDKは使い方さえ知ってしまえば非常に便利なものだと感じた。
また、参考文献の二つ目・三つ目の記事で触れられていたことだが、「運用の観点から見ると」GUIに頼りすぎないことが大事だと感じた。そのためにも、AWSサービスををCLI、SDKからスムーズに触ることができるように情報をキャッチアップしていきたい。

参考文献

https://dev.classmethod.jp/articles/how-to-use-awssdk-boto3-for-beginners/
https://www.opslab.jp/publish/20190223-jawsdays-cli.html
https://www.slideshare.net/TrainocateJ/automation-of-aws-operation-1st-step-by-trainocate-91616377
https://maku.blog/p/wht5epz/
https://laboratory.kazuuu.net/create-a-table-in-amazon-dynamodb-using-with-boto3-in-python/
https://qiita.com/shibataka000/items/e3f3792201d6fcc397fd#%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/scan.html#
https://dev.classmethod.jp/articles/boto3-client-api-and-resource-api/#toc-2