def get_database_config(parsed: ConfigParser, manager: ConfigManager) -> dict: """ Generate a populated configuration dictionary. TODO: This should be shared with dbManager.py. :param parsed: ConfigParser :param manager: ConfigManager :return: Dictionary """ config: dict = {} config['engine']: str = parsed.get('database', 'engine') if \ parsed.has_option('database', 'engine') else \ 'sqlite' config['host']: str = parsed.get('database', 'host') if \ parsed.has_option('database', 'host') else \ 'localhost' config['username']: str = parsed.get('database', 'username') if \ parsed.has_option('database', 'username') else \ manager.getDbUser() config['password']: str = parsed.get('database', 'password') if \ parsed.has_option('database', 'password') else \ manager.getDbPassword() if config['engine'] == 'sqlite': config['port']: Optional[int] = None config['path']: str = parsed.get('database', 'path') if \ parsed.has_option('database', 'path') else \ os.path.join( manager.getEtcDir(), manager.getDbSchema() + '.sqlite' ) elif config['engine'] == 'mysql': config['port']: Optional[int] = manager.get('database', 'port') if \ manager.has_option('database', 'port') else \ 3306 config['path']: str = manager.getDbSchema() else: raise NotImplementedError('{} is not supported'.format( config['engine'])) return config
class DbManager(TortugaObjectManager): """ Class for db management. :param engine: a SQLAlchemy database engine instance :param init: a flag that is set when the database has not yet been initialized. If this flag is set, not attempts will be made to load/map kit tables. This flag is cleared once the database has been initialized. """ def __init__(self, engine=None): super().__init__() if not engine: self._cm = ConfigManager() engine = self._cm.getDbEngine() schema = self._cm.getDbSchema() engineURI = self.__getDbEngineURI() if engine == 'sqlite' and not os.path.exists(schema): # Ensure SQLite database file is created with proper # permissions fd = os.open(schema, os.O_CREAT, mode=0o600) os.close(fd) self._engine = sqlalchemy.create_engine(engineURI, pool_size=100, max_overflow=100, pool_pre_ping=True) else: self._engine = engine self.Session = sqlalchemy.orm.scoped_session( sqlalchemy.orm.sessionmaker(bind=self.engine)) def _register_database_tables(self): for kit_installer_class in get_all_kit_installers(): kit_installer = kit_installer_class() kit_installer.register_database_tables() @property def engine(self): """ SQLAlchemy Engine object property """ self._register_database_tables() return self._engine def session(self): """ Database session context manager """ return SessionContextManager(self) def init_database(self): # # Create tables # self._register_database_tables() ModelBase.metadata.create_all(self.engine) @property def metadata(self): return self._metadata def __getDbEngineURI(self): engine = self._cm.getDbEngine() schema = self._cm.getDbSchema() driver = '' host = '' port = '' user = '' password = '' if engine == 'mysql': driver = "+pymysql" host = self._cm.getDbHost() port = self._cm.getDbPort() user = self._cm.getDbUser() password = self._cm.getDbPassword() userspec = '' if user: if password: userspec = '{}:{}@'.format(user, password) else: userspec = '{}@'.format(user) hostspec = '' if host: if port: hostspec = '{}:{}'.format(host, port) else: hostspec = host engineURI = "{}{}://{}{}/{}".format(engine, driver, userspec, hostspec, schema) return engineURI def getMetadataTable(self, table): return self._metadata.tables[table] def openSession(self): """ Open db session. """ return self.Session() def closeSession(self): """Close scoped_session.""" self.Session.remove()