user18764
user18764

Reputation: 253

can session with context manager replace scoped_session in threaded situations

sqlalchemy suggests the transaction pattern for sessions:

# myapp.py
from contextlib import contextmanager

engine = create_engine('sqlite:////tmp/test.db')
Session = sessionmaker(bind=engine)

@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = Session()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
...
with session_scope() as session:
   # do stuff

Furthermore, I have noticed that for web applications, session_scope should be used:

# my_scoped_app.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db')
db_session = scoped_session(sessionmaker(bind=engine))

...
# Some app definition
...


@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()           

Since I want to scale Flask beyond a single-thread, is it safe to use the first pattern? In other words, does it matter whether I implement some class like

from myapp import session_scope()

class Foo(object):
   def do_stuff(self, args):
      with session_scope() as session:
          do_more_stuff(session, args)

versus

from my_scoped_app import db_session:

class Foo(object):
   def do_stuff(self, args):
      session = db_session()
      do_more_stuff(session, args)
      session.commit()
      session.close()

Ignoring the differences in exception handling.

Upvotes: 2

Views: 2275

Answers (1)

Chan
Chan

Reputation: 23

What i found is that the first approach will create new session each time you call it. The second approach will firstly check if session for current thread exists and if not will also create new session.
Second approach is alot cleaner when dealing with session in different modules within same thread.
So technicly you're getting the same from both within single request while using it.

Upvotes: 1

Related Questions