2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SQLAlchemyでSELECT後に決まった処理を差し込む

2
Last updated at Posted at 2014-09-20

なんかSELECTして持ってきたあと、表示のためになんか加工したりだとか、そういう毎回する後処理を、SQLAlchemyだとどこに書くのかなーと思って。

今までは、SELECT系の自作メソッドに、後処理をする自作デコレータを明示的につけて対応してた。
でもこれだと、relationship とか使ってて、何か他のテーブルのついでにSELECTされた場合、後処理の自作ロジックを通ってくれない。当たり前だけど。すごください。

そうじゃなくて、どういう経緯であってもSELECTされたらすぐあとに確実に処理を実行したい。

Railsだとafter_findみたいなやつ、SQLAlchemyのイベントに似たようなのきっとあるんだろうなと思いつつ、ちょっと調べたけどやってる人見つからなくて、そのうち夏が秋になり、セミが全部死んだので、追悼の意を込め、ついにこの間重い腰を上げて公式ページ調べました。

まあ、近いのは、loadイベントなのかな?

test.py
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

おしまい。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?