Source code for assembl.lib.read_write_session
from contextlib import contextmanager
import sqlalchemy.orm as orm
from .logging import getLogger
log = getLogger()
[docs]class ReadWriteSession(orm.Session):
"""A session that can divert read queries to a different engine
Inspired by https://gist.github.com/adhorn/b84dc47175259992d406
"""
def __init__(self, bind=None, autoflush=False,
read_bind=None, readonly=False, **options):
self.read_bind = read_bind
if read_bind:
read_bind.is_readonly = True
orm.Session.__init__(
self, bind=bind, autoflush=autoflush, **options)
[docs] def get_bind(self, mapper=None, clause=None):
use_read = self.read_bind and not self._flushing and self.readonly
log.debug("using %s session%s" % (
"read" if use_read else "write",
" while flushing" if self._flushing else ""))
return self.read_bind if use_read else self.bind
def set_readonly(self, readonly=True):
if readonly and self._flushing:
log.error("cannot set readonly: already flushing")
else:
self.readonly = readonly
@contextmanager
def readonly(session):
was_readonly = session.readonly
try:
session.set_readonly(True)
yield session
finally:
session.set_readonly(was_readonly)