""" MySQL Connector. Manages interactions with MySQL for art_relations and direct_delivery databse. """ from contextlib import contextmanager import functools from oto import response from sqlalchemy import create_engine from sqlalchemy import event from sqlalchemy import exc from sqlalchemy import pool from sqlalchemy import select from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker import config def _create_engine(db_url): """Create engine based on config settings.""" if config.POOL_CLASS == pool.QueuePool: db_engine = create_engine( db_url, pool_size=config.POOL_SIZE, max_overflow=config.POOL_MAX_OVERFLOW, pool_recycle=config.POOL_RECYCLE_MS) return create_engine(db_url, poolclass=config.POOL_CLASS) # ar_db_engine = _create_engine(config.AR_DB_URL) # ar_database_session = sessionmaker(bind=ar_db_engine) au_db_engine = _create_engine(config.RDS_DB_URL) au_database_session = sessionmaker(bind=au_db_engine) oat_au_db_engine = _create_engine(config.OAT_DB_URL) oat_au_database_session = sessionmaker(bind=oat_au_db_engine) baseModel = declarative_base() #ArModel = declarative_base() AuModel = declarative_base() OATModel = declarative_base() @contextmanager def ar_db_session(): """ Provide transactional scope around series of operations for art_relations. 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 ar_database_session() as session: session.execute(query) """ session = ar_database_session() try: yield session session.commit() except: session.rollback() raise finally: session.close() @contextmanager def au_db_session(read_only=False): session = au_database_session() try: yield session if not read_only: session.commit() except: session.rollback() raise finally: session.close() @contextmanager def oat_au_db_session(): """ Provide a transactional scope around a series of operations. for asset_upload database for ows-asset-transcoder 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 oat_au_database_session() as session: session.execute(query) """ session = oat_au_database_session() try: yield session session.commit() except: 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 as exception: print(exception) return response.create_fatal_response() return function_return return call_function_with_error_handling