なんかSELECTして持ってきたあと、表示のためになんか加工したりだとか、そういう毎回する後処理を、SQLAlchemyだとどこに書くのかなーと思って。
今までは、SELECT系の自作メソッドに、後処理をする自作デコレータを明示的につけて対応してた。
でもこれだと、relationship とか使ってて、何か他のテーブルのついでにSELECTされた場合、後処理の自作ロジックを通ってくれない。当たり前だけど。すごください。
そうじゃなくて、どういう経緯であってもSELECTされたらすぐあとに確実に処理を実行したい。
Railsだとafter_findみたいなやつ、SQLAlchemyのイベントに似たようなのきっとあるんだろうなと思いつつ、ちょっと調べたけどやってる人見つからなくて、そのうち夏が秋になり、セミが全部死んだので、追悼の意を込め、ついにこの間重い腰を上げて公式ページ調べました。
まあ、近いのは、loadイベントなのかな?
class Tests(ModelsBase, Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
name = Column(Text)
status = Column(SmallInteger, server_default='1')
insert_date = Column(DateTime, server_default=func.now())
update_date = Column(DateTime, server_default=func.now(), onupdate=func.current_timestamp())
def __repr__(self):
return '<Tests id:{0}, name:{1}>'.format(self.id, name)
def tests_load_listener(target, context):
# targetはTestsのインスタンス。
# 表示用の加工とか、属性生やしたり
if target.name:
target.name_for_disp = target.name + '様'
else:
target.name_for_disp = 'ななし君'
event.listen(Tests, 'load', tests_load_listener)
ご多分に漏れず、selectされた件数分イベント発生するので、考えて使わないと死ぬけど、満足しました。
load のほかに良さそうなのは refresh というのもあって、これは属性に変更があるたびに呼ばれるので、これもつけておくと、こう、UPDATE直後も整ってます、みたいな感じでかっこいいかもしれない。
ほかにもイベントはいっぱいあった。
http://docs.sqlalchemy.org/en/latest/orm/events.html
おしまい。