"""Mysql connector.""" from contextlib import contextmanager import functools from sqlalchemy import create_engine from sqlalchemy import exc from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from ows_accounting import config from ows_accounting import response from ows_accounting.utils import sentry # please don't use the following private variables directly; # use db_session _db_engine = create_engine( config.DB_CONNECTION_URL, poolclass=config.POOLCLASS) BaseModel = declarative_base() _db_session = sessionmaker(bind=_db_engine) _holds_db_engine = create_engine( config.PAYMENT_HOLDS_DB_URL, poolclass=config.POOLCLASS) _holds_db_session = sessionmaker(bind=_holds_db_engine) @contextmanager def db_session(expire_on_commit=True): """Provide a transactional scope around a series of operations. Taken from http://docs.sqlalchemy.org/en/latest/orm/session_basics.html. This handles rollback and closing of session, so there is no need to do that throughout the code. Usage: with db_session() as session: session.execute(query) """ session = _db_session(expire_on_commit=expire_on_commit) try: yield session session.commit() except: # noqa session.rollback() raise finally: session.close() @contextmanager def holds_db_session(expire_on_commit=True): """Provide a transactional scope around a series of operations on holds. with holds_db_session() as session: session.execute(query) """ session = _holds_db_session(expire_on_commit=expire_on_commit) try: yield session session.commit() except: # noqa session.rollback() raise finally: session.close() def wrap_db_errors(function): """Decorate the given function with logic to handle SQLAlchemy errors. If a SQLAlchemy exception is thrown, it will be caught and logged and the function will return a fatal response. Args: function (func): the function to decorate Returns: func: function decorated with error-handling logic """ @functools.wraps(function) def call_function_with_error_handling(*args, **kwargs): try: function_return = function(*args, **kwargs) except exc.SQLAlchemyError: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response() return function_return return call_function_with_error_handling