LoginSignup
72
55

More than 3 years have passed since last update.

SQLAlchemyのSession生成方法

Last updated at Posted at 2019-05-16

概要

SQLAlchemyのSessionの生成方法はいくつかあります。
ここではそれらの生成方法を一つ一つ説明していきます。

調査した時の各バージョン

  • SQLAlchemy : 1.3.3

Session生成方法の種類

Sessionの生成方法には以下のような種類があります。

  • Sessionクラスによる生成(基本)
  • sessionmakerによる生成
  • scoped_sessionによる生成
  • scoped_sessionによる生成(ORM編)

①Sessionクラスによる生成(基本)

基本的な生成方法です。
SessionクラスからSessionインスタンスを生成するんだから一番わかりやすいですね。
例えばこんな感じで生成します。

main.py
from sqlalchemy import create_engine
from sqlalchemy.orm import Session

engine = create_engine()

# Sessionインスタンスの生成
session = Session(
    autocommit = False,
    autoflush = True,
    bind = engine)

引数は大体この3つを指定していることが多いです。但し、autocommit=Falseautoflush=Trueはデフォルト値である為、省略も可能です。

注意点としては、session = Session()を実行する度に新しいSessionが生成されるということでしょうか。

②sessionmakerによる作成

sessionmakerクラスを使用してSessionを生成します。
公式のドキュメントでは、Sessionクラスによる生成よりこちらを推しています。

settings.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine()

# この時点ではまだSessionインスタンスは生成されていない
# Session変数に格納されているのは実はsessionmakerインスタンス
Session = sessionmaker(
    autocommit = False,
    autoflush = True,
    bind = engine)
main.py
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管理レジストリを内包したクラスによる生成方法です。

settings.py
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))   
main.py
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と連携させた時です。

settings.py
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()
model.py
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))
main.py
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を実行するちょっとしたツールくらいなら①や②で十分でしょう。

とりあえず調べた限りではこれくらいでしたが、他の生成方法を知ってる方がいましたらご教示くださいー

72
55
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
72
55