この記事はPython Advent Calendar 2020の22日目の記事です。 ちょうど空いていたので書こうかなと思います。

DynamoDBを使うライブラリとしてPynamoDBというものがあります。 そのPynamoDBのMapAtttributeの大まかな使い方を調べた内容を纏めます。

MapAttribute

MapAttributeを用いることでDynamoDBの属性として保持する辞書の形式を宣言的に定義できます。

テーブルの定義

以下のような例を考えます。

  • ユーザーテーブルがある。

  • ユーザーテーブルはidをハッシュキーとして持つ。

  • ユーザーテーブルはprofileという属性を持つ。

  • ユーザーテーブルのprofile属性はnameをキーとして持つ辞書。

つまりユーザーテーブルの1つのレコードは以下のようになります。

{
  "id": 1,
  "profile": {
    "name": "foo"
  }
}

このprofile属性をMapAttributeとして表現するようなPynamoDBの定義は次のようになります。

from pynamodb.attributes import MapAttribute, NumberAttribute, UnicodeAttribute
from pynamodb.models import Model


class Profile(MapAttribute):
    name = UnicodeAttribute()


class User(Model):
    class Meta:
        table_name = "user"
        # region = "ap-northeast-1"
        # host = "http://host.docker.internal:4566"

    id = NumberAttribute(hash_key=True)
    profile = Profile()

大まかな使い方

先のユーザーテーブルに新しいカラムを追加します。 profileにはProfileクラスのインスタンスを渡します。

>>> u = User(id=4, profile=Profile(name="foo"))
>>> u.save()
{'ConsumedCapacity': {'TableName': 'user', 'CapacityUnits': 1.0}}
>>>

id=4のユーザーを取得します。

>>> u = User.get(hash_key=4)

このprofile属性はProfileクラスのインスタンスとなります。

>>> u.profile
<__main__.Profile object at 0x10e760e20>
>>> u.profile.name
'foo'

profile.nameを変更して保存します。


>>> u.profile.name = "bar"
>>> u.save()
{'ConsumedCapacity': {'TableName': 'user', 'CapacityUnits': 1.0}}

おわりに

短いですが以上になります。 それではメリークリスマス。