DynaModelを継承したクラス経由で生成したレコードのnullの取扱いで困ったときのメモ
環境
Python 3.6.1
事象
-
boto3ライブラリのDynaModelクラスのputメソッドを使って
DynamoDBにレコードを登録した際、nullableなカラムに明示的にnullを入れても
生成されたレコードにカラムが出来上がらない。→ライブラリ側の仕様でputメソッド内でレコード生成時にnull入りカラムは明示的に除去している様子。
上記の除去されたカラムを含むレコードを取得してきてSchemaクラスで定義しているフィールド(カラム)に
普通にアクセスしようとするとAttributeErrorで叩き落ちる。
対応
その1
nullの可能性があるカラムのみ、ビルドイン関数のhasattrを使用して判定してからアクセス。
attribute = model.attribute if hasattr(model, "attribute") else None
その2
追加開発するタイミングとかで必須カラムを追加することになったりして、
すべての必須カラムがnullになりうるとする。
「都度都度hasattr噛ませたり噛ませるための関数を呼ぶのうざくない?」と思い至り
DynaModelクラスを拡張して、ほぼ恒久的にこの件を気にしなくて済む方法を考えてみた。
こっちがメモを残しておきたい本題。
from dynamorm import DynaModel as BaseDynaModel
class DynaModel(BaseDynaModel):
def __getattr__(self, item):
field_names = self.Schema.dynamorm_fields().keys()
if item in field_names:
return None
else:
raise AttributeError(
": '{}' object has no attribute '{}'".format(
self.__class__.__name__, item)
)
__getattr__
がPythonのクラスに標準搭載されている隠しメソッドで、
存在しないカラム(フィールド)へアクセスしたタイミングでのみ呼ばれる。
このメソッドが呼ばれるタイミングでNone返せば叩き落ちずに済む。
ただし、Schemaクラスで定義済みのもののみNoneを返したくて、
他のパターンはエラー返さないとバグ検知できなくなっちゃうのは避けたかったので、
Schemaクラスへ定義済みのフィールドを全部返してくれる
dynamorm_fields()
ってライブラリ内で用意されてる関数を使って定義有無確認の処理を挟んだ。
参考
Swiftでいう変数に直接設定できるゲッターセッター的なものがPythonにはないのだろうかと
あれこれググって、以下の記事で__getattr__
について見つけてとても助かりましたm(_ _)m
Author And Source
この問題について(DynaModelを継承したクラス経由で生成したレコードのnullの取扱いで困ったときのメモ), 我々は、より多くの情報をここで見つけました https://qiita.com/m-yamada1992/items/ad17caca04a70666f41c著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .