SQLAlchemy の Session に型ヒントをつけたい。
◯ 結論
sqlalchemy.orm.session.Session
を使います。
# sessionmaker は 「クラスオブジェクト」です。
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.session import Session as BaseSession
...
# Session は 「関数」です。
# 「インスタンスオブジェクト」であり
# 「クラスオブジェクト」ではありません。
Session = sessionmaker(bind=engine)
# session は
# BaseSession クラスを継承したクラスの「インスタンスオブジェクト」です。
session: BaseSession = Session()
...
session.commit()
session.close()
◯ 根拠
上記の Session
は sqlalchemy.orm.session.Session
の子クラスのインスタンスオブジェクトを返すからです。
class sessionmaker(_SessionClassMethods):
...
def __init__(
self,
bind=None,
# vvv class_ (Session) は sqlalchemy.orm.session.Session
class_=Session,
autoflush=True,
autocommit=False,
expire_on_commit=True,
info=None,
**kw
):
...
# class_ (Session) を継承したクラスオブジェクトを代入する。
self.class_ = type(class_.__name__, (class_,), {})
def __call__(self, **local_kw):
...
# class_ (Session) を継承したクラスオブジェクトを
# インスタンス化する。
return self.class_(**local_kw)
- /sqlalchemy/orm/session.py#L3187-L3279 - GitHub
- Type hints for SQLAlchemy engine and session objects - Stackoverflow
◯ 疑問
1. リスコフの置換則
Session
と BaseSession
が、もしリスコフの置換則を満たしていなかったら、上記のように型付できず、間違っていることになります。
ぱっコードを見たところ問題はなさそうなのと、実際に使っていて問題はないので、大丈夫なのかなと 思っています 。
2. 命名規則
sessionmaker
は、命名規則的にはインスタンスオブジェクトです。しかし、実際にはクラスオブジェクトが代入されています。
3. 振る舞い
sessionmaker
がインスタンス化したインスタンスオブジェクト Session
は、クラスオブジェクトではないのに、あたかもクラスオブジェクトのように動作していること。
Session
を、あるクラスのインスタンスを返す関数と考えればいいだけの話なのですが。Session
と先頭を大文字にしてクラスとして扱った方が全体のコードが綺麗になるような気がするので。
Author And Source
この問題について(SQLAlchemy の Session に型ヒントをつけたい。), 我々は、より多くの情報をここで見つけました https://qiita.com/domodomodomo/items/4d5c79887188152c6e72著者帰属:元の著者の情報は、元の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 .