"""Mysql Connector.""" import functools from contextlib import contextmanager from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import QueuePool from account import config # please don't use the following private variables directly; # use db_session if config.POOL_CLASS == QueuePool: _account_engine = create_engine( config.DB_URL, pool_size=config.POOL_SIZE, max_overflow=config.POOL_MAX_OVERFLOW, pool_recycle=config.POOL_RECYCLE_MS, connect_args=config.CONNECT_ARGS, ) else: _account_engine = create_engine(config.DB_URL, connect_args=config.CONNECT_ARGS) BaseModel = declarative_base() # A session() instance establishes all conversations with the database # and represents a "staging zone" for all the objects loaded into the # database session object. Any change made against the objects in the # session won't be persisted into the database until you call # session.commit(). If you're not happy about the changes, you can # revert all of them back to the last commit by calling # session.rollback() # # Description taken from: # pythoncentral.io/introductory-tutorial-python-sqlalchemy/ _account_session = sessionmaker(bind=_account_engine) @contextmanager def session_scope(read_only=False): """Provide transactional scope. Taken from http://docs.sqlalchemy.org/en/latest/orm/session_basics.html. Handles commit, rollback, and closing of sessions. Usage: with session_scope() as session: session.execute(query) """ session = _account_session() try: yield session if not read_only: session.commit() except: session.rollback() raise finally: session.close() def db_read_only_session_wrap(func): """Wrap shared read-only session. Creates a new read-only session if one isn't passed in. This lets us share/pass-in a common session across multiple functions. """ @functools.wraps(func) def wrapper(*args, **kwargs): session = kwargs.pop('session', None) if session: return func(*args, session=session, **kwargs) else: with session_scope(read_only=True) as session: return func(*args, session=session, **kwargs) return wrapper