概要
SQLAlchemyのSessionの生成方法はいくつかあります。
ここではそれらの生成方法を一つ一つ説明していきます。
調査した時の各バージョン
- SQLAlchemy : 1.3.3
Session生成方法の種類
Sessionの生成方法には以下のような種類があります。
- Sessionクラスによる生成(基本)
- sessionmakerによる生成
- scoped_sessionによる生成
- scoped_sessionによる生成(ORM編)
①Sessionクラスによる生成(基本)
基本的な生成方法です。
SessionクラスからSessionインスタンスを生成するんだから一番わかりやすいですね。
例えばこんな感じで生成します。
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
engine = create_engine(~略~)
# Sessionインスタンスの生成
session = Session(
autocommit = False,
autoflush = True,
bind = engine)
引数は大体この3つを指定していることが多いです。但し、autocommit=False
、autoflush=True
はデフォルト値である為、省略も可能です。
注意点としては、session = Session()
を実行する度に新しいSessionが生成されるということでしょうか。
②sessionmakerによる作成
sessionmakerクラスを使用してSessionを生成します。
公式のドキュメントでは、Sessionクラスによる生成よりこちらを推しています。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine(~略~)
# この時点ではまだSessionインスタンスは生成されていない
# Session変数に格納されているのは実はsessionmakerインスタンス
Session = sessionmaker(
autocommit = False,
autoflush = True,
bind = engine)
from settings import Session
# Sessionインスタンスの生成
# settings.pyで指定した引数でSessionが生成される
session = Session()
この生成方法であればSessionを生成する際に引数を指定する必要がなく、常に同じ引数でSessionが生成されます。但し、session = Session()
を実行する度に新しいSessionが生成されるのはSessionクラスによる生成と同様です。
※ただ、実際に書くコードでは毎回session = Session()
はせずにsettings.py
辺りで一回だけSessionを生成してそれを使い回すことが多いと思うので、そうすると①と②はあまり違わない気もします。。
③scoped_sessionによる生成
scoped_sessionという内部にSession管理レジストリを内包したクラスによる生成方法です。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
engine = create_engine(~略~)
# この時点ではまだSessionインスタンスは生成されていない
# Session変数に格納されているのは実はscoped_sessionインスタンス
Session = scoped_session(
sessionmaker(
autocommit = False,
autoflush = True,
bind = engine))
from settings import Session
# Sessionインスタンスの生成
# settings.pyで指定した引数でSessionが生成される
session01 = Session()
# session01とsession02は同一のSession
session02 = Session()
sessionmakerインスタンスを内包したscoped_sessionインスタンスを生成して、そのインスタンスからSessionを生成しています。sessionmakerとの違いは、Session()
を何回実行しても同一のSessionが返されるという点です。
ただ、この方法もこれだけだとsessionmaker等と比較して凄く良いかと言われると、そこまででもないかなって感じです。(②のところで書いたように、同一のSessionを使い回したいだけならsettings.py
で予め生成しておけばいいですし。。)
④scoped_sessionによる生成(ORM編)
scoped_sessionが効果を発揮するのはやはりORMと連携させた時です。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine(~略~)
session = scoped_session(
sessionmaker(
autocommit = False,
autoflush = True,
bind = engine))
Base = declarative_base()
# 予めテーブル定義の継承元クラスにqueryプロパティを仕込んでおく
Base.query = session.query_property()
from sqlalchemy import Column, Integer, String
from settings import Base
# UserクラスはBaseを継承しているのでqueryプロパティを持つ
# XXX: ここで直接queryプロパティを仕込んでも良い
class User(Base):
__tablename__ = 'user_list'
id = Column('id', Integer, primary_key=True)
name = Column('name', String(100))
from settings import session
from model import User
# Seesionを使ってるように見えないが内部的に使ってる
result = User.query.filter_by(id == 1).all()
# 特にcommitに意味はないけどサンプルコードとして
session.commit()
上記コードのUser.query.~
のように、テーブルクラスを起点としてコード(select文)が書けるようになります。(ORMっぽい・・ぽくない?)
User.query.~
は、session.query(User).~
と同義です。
また、「③scoped_sessionによる生成」でsession01 = Session()
と書きましたが、実はsession01 = Session()
と明示的に記述するまでもありません。上記コードのsession.commit()
のようにいきなりSessionを使い始めることができます。session.commit()
はsession().commit()
と同義です。
まとめ
ORMを使うなら④のような構成にしておくと柔軟にコードを書くことができると思います。逆に生SQLを実行するちょっとしたツールくらいなら①や②で十分でしょう。
とりあえず調べた限りではこれくらいでしたが、他の生成方法を知ってる方がいましたらご教示くださいー