Commit a8734f79 authored by sveseli's avatar sveseli
Browse files

added aps user db implementation and api classes

parent 5b57c724
#!/usr/bin/env python
from dm.aps_user_db.api.apsUserDbApiBase import ApsUserDbApiBase
from dm.aps_user_db.impl.apsUserInfoHandler import ApsUserInfoHandler
class ApsUserDbApi(ApsUserDbApiBase):
""" APS User DB API class. """
def __init__(self):
ApsUserDbApiBase.__init__(self)
self.userInfoHandler = ApsUserInfoHandler()
@ApsUserDbApiBase.executeQuery
def getApsUsers(self, **kwargs):
session = kwargs['session']
dbUsers = self.userInfoHandler.getApsUsers(session)
return self.toDmObjectList(dbUsers)
@ApsUserDbApiBase.executeQuery
def getApsUserByBadgeNumber(self, badgeNumber, **kwargs):
session = kwargs['session']
dbUserInfo = self.userInfoHandler.getApsUserByBadgeNumber(session, badgeNumber)
return dbUserInfo.getDmObject()
#######################################################################
# Testing.
if __name__ == '__main__':
api = ApsUserDbApi()
#users = api.getApsUsers()
#for u in users:
# print u
print api.getApsUserByBadgeNumber(225159)
#!/usr/bin/env python
from dm.common.exceptions.dmException import DmException
from dm.common.exceptions.internalError import InternalError
from dm.common.utility.loggingManager import LoggingManager
from dm.aps_user_db.impl.apsUserDbManager import ApsUserDbManager
class ApsUserDbApiBase:
""" APS User DB API base class. """
def __init__(self):
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
self.dbManager = ApsUserDbManager.getInstance()
# Decorator for all DB queries
@classmethod
def executeQuery(cls, func):
def query(*args, **kwargs):
try:
dbManager = ApsUserDbManager.getInstance()
session = dbManager.openSession()
kwargs['session'] = session
try:
return func(*args, **kwargs)
except DmException, ex:
raise
except Exception, ex:
cls.getLogger().exception('%s' % ex)
raise DmException(exception=ex)
finally:
dbManager.closeSession(session)
return query
# Decorator for all DB transactions
@classmethod
def executeTransaction(cls, func):
def transaction(*args, **kwargs):
try:
dbManager = ApsUserDbManager.getInstance()
session = dbManager.openSession()
kwargs['session'] = session
try:
result = func(*args, **kwargs)
session.commit()
return result
except DmException, ex:
session.rollback()
raise
except Exception, ex:
session.rollback()
cls.getLogger().exception('%s' % ex)
raise DmException(exception=ex)
finally:
dbManager.closeSession(session)
return transaction
@classmethod
def getLogger(cls):
logger = LoggingManager.getInstance().getLogger(cls.__name__)
return logger
@classmethod
def executeConnectionQuery(cls, query):
connection = None
try:
connection = ApsUserDbManager.getInstance().acquireConnection()
try:
return connection.execute(query)
except DmException, ex:
raise
except Exception, ex:
cls.getLogger().exception('%s' % ex)
raise
finally:
ApsUserDbManager.getInstance().releaseConnection(connection)
def loadRelation(self, dbObject, relationName):
if not relationName in dir(dbObject):
raise InternalError('Relation %s not valid for class %s'
% (relationName, dbObject.__class__.__name__))
o = None
exec 'o = dbObject.%s' % (relationName)
return o
def loadRelations(self, dbObject, optionDict):
for k in optionDict.keys():
# The optionDict contains key-value pairs of relation name
# and a boolean to indicate whether to load that relation
if not optionDict[k]:
continue
try:
self.loadRelation(dbObject, k)
except InternalError, ex:
self.logger.error(ex)
def toDmObjectList(self, dbEntityList):
dmObjectList = []
for dbEntity in dbEntityList:
dmObjectList.append(dbEntity.getDmObject())
return dmObjectList
#######################################################################
# Testing.
if __name__ == '__main__':
api = ApsUserDbApiBase()
#!/usr/bin/env python
from dm.aps_user_db.entities.apsUserInfo import ApsUserInfo
# Map db table/db entity class
# Use generic 'self' key as name for primary key mapping (needed by sqlalchemy)
APS_USER_DB_ENTITY_MAP = {
'FL$03_BL_APV_VIEW_V2' : (ApsUserInfo, {'self' : {'primary_key' : 'badge_no'}}),
}
#!/usr/bin/env python
from dm.common.db.entities.dmDbEntity import DmDbEntity
from dm.common.objects import apsUserInfo
class ApsUserInfo(DmDbEntity):
mappedColumnDict = {
'badge_no' : 'badgeNumber',
'first_name' : 'firstName',
'middle_name' : 'middleName',
'last_name' : 'lastName',
'last_change_date' : 'lastChangeDate',
'pwd_hash_value' : 'passwordHashValue',
'is_usr_not_anl_emp' : 'isUserNotAnlEmployee',
}
dmObjectClass = apsUserInfo.ApsUserInfo
def __init__(self, **kwargs):
DmDbEntity.__init__(self, **kwargs)
#!/usr/bin/env python
import threading
import os.path
import sqlalchemy
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import mapper
from sqlalchemy.orm import relationship
from dm.common.exceptions.commandFailed import CommandFailed
from dm.common.exceptions.configurationError import ConfigurationError
from dm.common.utility.loggingManager import LoggingManager
from dm.common.utility.configurationManager import ConfigurationManager
from dm.aps_user_db.entities import apsUserDbEntityMap
class ApsUserDbManager:
""" Singleton class for db management. """
DB_CONNECTION_POOL_SIZE = 10
DB_CONNECTION_POOL_MAX_OVERFLOW = 2
DB_CONNECTION_POOL_RECYCYLE_TIME = 600
DB_CONNECTION_POOL_TIMEOUT = 60
DB_CONNECTION_LOGGING_FLAG = False
CONFIG_SECTION_NAME = 'ApsUserDbManager'
CONFIG_OPTION_NAME_LIST = [ 'dbHost', 'dbPort', 'dbUser', 'dbPasswordFile', 'dbName', 'dbSchema' ]
# Singleton.
__lock = threading.RLock()
__instance = None
@classmethod
def getInstance(cls):
from dm.aps_user_db.impl.apsUserDbManager import ApsUserDbManager
try:
mgr = ApsUserDbManager()
except ApsUserDbManager, ex:
mgr = ex
return mgr
def __init__(self):
ApsUserDbManager.__lock.acquire()
try:
if ApsUserDbManager.__instance is not None:
raise ApsUserDbManager.__instance
ApsUserDbManager.__instance = self
self.lock = threading.RLock()
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
cm = ConfigurationManager.getInstance()
#cm.setOptionsFromConfigFile(ApsUserDbManager.CONFIG_SECTION_NAME, ApsUserDbManager.CONFIG_OPTION_NAME_LIST)
#dbUser = cm.getDbUser()
#self.logger.debug('Using DB user: %s' % dbUser)
#dbSchema = cm.getDbSchema()
#dbPasswordFile = cm.getDbPasswordFile()
#self.logger.debug('Using DB password file: %s' % dbPasswordFile)
#dbPassword = open(dbPasswordFile, 'r').readline().strip()
#dbPort = cm.getDbPort()
#dbHost = cm.getDbHost()
#db = cm.getDb()
db = "oracle"
dbPort = 1527
dbHost = "ra.aps.anl.gov"
dbName = "aps1"
dbSchema = "DCC"
dbUser = "glob_conn"
dbPassword = "ur2ytkownicy2u"
engineUrl = '%s://%s:%s@%s:%s/%s' % (db, dbUser, dbPassword, dbHost, dbPort, dbName)
self.logger.debug('Using engine URL: %s' % engineUrl)
self.engine = sqlalchemy.create_engine(engineUrl,
pool_size=ApsUserDbManager.DB_CONNECTION_POOL_SIZE,
max_overflow=ApsUserDbManager.DB_CONNECTION_POOL_MAX_OVERFLOW,
pool_recycle=ApsUserDbManager.DB_CONNECTION_POOL_RECYCYLE_TIME,
echo=ApsUserDbManager.DB_CONNECTION_LOGGING_FLAG,
pool_timeout=ApsUserDbManager.DB_CONNECTION_POOL_TIMEOUT)
self.metadata = sqlalchemy.MetaData(engineUrl, schema=dbSchema)
self.logger.debug('Mapping DB tables')
for (dbTableName, (dbEntityClass, dbRelationDict)) in apsUserDbEntityMap.APS_USER_DB_ENTITY_MAP.items():
self.mapTable(dbEntityClass, dbTableName, dbRelationDict)
self.logger.debug('Initialized SQLalchemy engines')
finally:
ApsUserDbManager.__lock.release()
def getLogger(self):
return self.logger
def inspectTables(self):
from sqlalchemy import inspect
inspector = inspect(self.engine)
self.logger.debug('Inspecting tables')
for tableName in inspector.get_table_names():
self.logger.debug('Table: %s' % tableName)
for column in inspector.get_columns(tableName):
self.logger.debug('Column: %s' % column['name'])
def inspectTables2(self):
from sqlalchemy import MetaData
m = MetaData()
m.reflect(self.engine)
self.logger.debug('Inspecting tables via metadata')
for table in m.tables.values():
self.logger.debug('Table: %s' % table.name)
for column in table.c:
self.logger.debug('Column: %s' % column.name)
def initTable(self, tableClass, tableName):
""" Initialize DB table. """
self.lock.acquire()
try:
tbl = sqlalchemy.Table(tableName, self.metadata, autoload=True)
tableClass.columns = tbl.columns
return tbl
finally:
self.lock.release()
def mapTable(self, tableClass, tableName, relationDict):
""" Map DB table to a given class. """
self.lock.acquire()
try:
table = sqlalchemy.Table(tableName, self.metadata, autoload=True)
tableClass.columns = table.columns
# Build relations from specified foreign key columns and other properties.
tableRelations = {}
primaryKey = None
for (name, propertyDict) in relationDict.items():
if name == 'self':
primaryKey = propertyDict.get('primary_key')
continue
lazy = propertyDict.get('lazy')
parentEntity = propertyDict.get('parentEntity')
foreignKeyColumns = propertyDict.get('foreignKeyColumns', [])
if len(foreignKeyColumns):
fkList = []
for fk in foreignKeyColumns:
fkList.append(table.columns.get(fk))
tableRelations[name] = relationship(parentEntity, foreign_keys=fkList, lazy=lazy)
else:
tableRelations[name] = relationship(parentEntity, lazy=lazy)
if primaryKey:
mapper(tableClass, table, tableRelations, primary_key=table.columns.get(primaryKey))
else:
mapper(tableClass, table, tableRelations)
return table
finally:
self.lock.release()
def getMetadataTable(self, table):
return self.metadata.tables[table]
def openSession(self):
""" Open db session. """
self.lock.acquire()
try:
Session = sessionmaker(bind=self.engine)
return Session()
finally:
self.lock.release()
def closeSession(self, session):
""" Close db session. """
self.lock.acquire()
try:
session.close()
finally:
self.lock.release()
def acquireConnection(self):
""" Get db connection. """
self.lock.acquire()
try:
return self.engine.connect()
finally:
self.lock.release()
def releaseConnection(self, connection):
""" Release db connection. """
self.lock.acquire()
try:
if connection:
connection.close()
finally:
self.lock.release()
#######################################################################
# Testing.
if __name__ == '__main__':
ConfigurationManager.getInstance().setConsoleLogLevel('debug')
mgr = ApsUserDbManager.getInstance()
mgr.acquireConnection()
mgr.inspectTables()
mgr.inspectTables2()
print 'Got connection'
#!/usr/bin/env python
from sqlalchemy import and_
from sqlalchemy.orm.exc import NoResultFound
from dm.common.exceptions.objectAlreadyExists import ObjectAlreadyExists
from dm.common.exceptions.objectNotFound import ObjectNotFound
from dm.common.exceptions.objectAlreadyExists import ObjectAlreadyExists
from dm.common.db.impl.dmDbEntityHandler import DmDbEntityHandler
from dm.aps_user_db.entities.apsUserInfo import ApsUserInfo
class ApsUserInfoHandler(DmDbEntityHandler):
def __init__(self):
DmDbEntityHandler.__init__(self)
def getApsUsers(self, session):
dbUserInfos = session.query(ApsUserInfo).all()
return dbUserInfos
def getApsUserByBadgeNumber(self, session, badgeNumber):
try:
dbUserInfo = session.query(ApsUserInfo).filter(ApsUserInfo.badge_no==badgeNumber).one()
return dbUserInfo
except NoResultFound, ex:
raise ObjectNotFound('APS user with badge number %s does not exist.' % (badgeNumber))
#!/usr/bin/env python
import threading
import os.path
import sqlalchemy
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import mapper
from sqlalchemy.orm import relationship
from dm.common.exceptions.commandFailed import CommandFailed
from dm.common.exceptions.configurationError import ConfigurationError
from dm.common.utility.loggingManager import LoggingManager
from dm.common.utility.configurationManager import ConfigurationManager
from dm.common.oracle.entities import oracleDbEntityMap
class OracleDbManager:
""" Singleton class for db management. """
DB_CONNECTION_POOL_SIZE = 10
DB_CONNECTION_POOL_MAX_OVERFLOW = 2
DB_CONNECTION_POOL_RECYCYLE_TIME = 600
DB_CONNECTION_POOL_TIMEOUT = 60
DB_CONNECTION_LOGGING_FLAG = False
CONFIG_SECTION_NAME = 'OracleDbManager'
CONFIG_OPTION_NAME_LIST = [ 'dbSchema', 'dbUser', 'dbPasswordFile' ]
# Singleton.
__lock = threading.RLock()
__instance = None
@classmethod
def getInstance(cls):
from dm.common.oracle.impl.oracleDbManager import OracleDbManager
try:
mgr = OracleDbManager()
except OracleDbManager, ex:
mgr = ex
return mgr
def __init__(self):
OracleDbManager.__lock.acquire()
try:
if OracleDbManager.__instance is not None:
raise OracleDbManager.__instance
OracleDbManager.__instance = self
self.lock = threading.RLock()
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
cm = ConfigurationManager.getInstance()
#cm.setOptionsFromConfigFile(OracleDbManager.CONFIG_SECTION_NAME, OracleDbManager.CONFIG_OPTION_NAME_LIST)
#dbUser = cm.getDbUser()
#self.logger.debug('Using DB user: %s' % dbUser)
#dbSchema = cm.getDbSchema()
#dbPasswordFile = cm.getDbPasswordFile()
#self.logger.debug('Using DB password file: %s' % dbPasswordFile)
#dbPassword = open(dbPasswordFile, 'r').readline().strip()
#dbPort = cm.getDbPort()
#dbHost = cm.getDbHost()
#db = cm.getDb()
db = "oracle"
dbPort = 1527
dbHost = "ra.aps.anl.gov"
dbSchema = "aps1"
dbUser = "glob_conn"
dbPassword = "ur2ytkownicy2u"
#self.logger.debug('DB schema: %s' % dbSchema)
#self.logger.debug('DB password file: %s' % dbPasswordFile)
engineUrl = '%s://%s:%s@%s:%s/%s' % (db, dbUser, dbPassword, dbHost, dbPort, dbSchema)
self.logger.debug('Using engine URL: %s' % engineUrl)
self.engine = sqlalchemy.create_engine(engineUrl,
pool_size=OracleDbManager.DB_CONNECTION_POOL_SIZE,
max_overflow=OracleDbManager.DB_CONNECTION_POOL_MAX_OVERFLOW,
pool_recycle=OracleDbManager.DB_CONNECTION_POOL_RECYCYLE_TIME,
echo=OracleDbManager.DB_CONNECTION_LOGGING_FLAG,
pool_timeout=OracleDbManager.DB_CONNECTION_POOL_TIMEOUT)
self.metadata = sqlalchemy.MetaData(engineUrl, schema='DCC')
print self.metadata
# 'DCC.FL$03_BL_APV_VIEW_V2'
self.metadata.reflect(self.engine, schema='DCC')
print self.metadata.tables
print self.metadata.__dict__
view = sqlalchemy.Table('FL$03_BL_APV_VIEW_V2', self.metadata, autoload=True) #, schema='DCC')
print 'VIEW:', view.__dict__
view.c.badge_no.primary_key=True
#view.c.last_name.primary_key=True
for column in view.columns:
self.logger.debug('Column: %s' % column.name)
self.logger.debug('%s' % column.__dict__)
self.logger.debug('Mapping DB tables')
from dm.common.oracle.entities.oracleUserInfo import OracleUserInfo
#mapper(OracleUserInfo, view, primary_key=[view.c.last_name])
mapper(OracleUserInfo, view, primary_key=[view.c.badge_no])
#for (dbTableName, (dbEntityClass, dbRelationDict)) in oracleDbEntityMap.ORACLE_DB_ENTITY_MAP.items():
# self.mapTable(dbEntityClass, dbTableName, dbRelationDict)
self.logger.debug('Initialized SQLalchemy engines')
finally:
OracleDbManager.__lock.release()
def getLogger(self):
return self.logger
def inspectTables(self):
from sqlalchemy import inspect
inspector = inspect(self.engine)
self.logger.debug('Inspecting tables')
for tableName in inspector.get_table_names():
self.logger.debug('Table: %s' % tableName)
for column in inspector.get_columns(tableName):
self.logger.debug('Column: %s' % column['name'])
def inspectTables2(self):
from sqlalchemy import MetaData
m = MetaData()
m.reflect(self.engine)
self.logger.debug('Inspecting tables via metadata')
for table in m.tables.values():
self.logger.debug('Table: %s' % table.name)
for column in table.c:
self.logger.debug('Column: %s' % column.name)
def initTable(self, tableClass, tableName):
""" Initialize DB table. """
self.lock.acquire()
try:
tbl = sqlalchemy.Table(tableName, self.metadata, autoload=True)
tableClass.columns = tbl.columns
return tbl
finally:
self.lock.release()
def mapTable(self, tableClass, tableName, relationDict):
""" Map DB table to a given class. """
self.lock.acquire()
try:
table = sqlalchemy.Table(tableName, self.metadata, autoload=True)
tableClass.columns = table.columns
# Build relations from specified foreign key columns and other properties.
tableRelations = {}
primaryKey = None
for (name, propertyDict) in relationDict.items():
if name == 'self':
primaryKey = propertyDict.get('primary_key')
continue
lazy = propertyDict.get('lazy')
parentEntity = propertyDict.get('parentEntity')
foreignKeyColumns = propertyDict.get('foreignKeyColumns', [])
if len(foreignKeyColumns):
fkList = []
for fk in foreignKeyColumns:
fkList.append(table.columns.get(fk))
tableRelations[name] = relationship(parentEntity, foreign_keys=fkList, lazy=lazy)
else:
tableRelations[name] = relationship(parentEntity, lazy=lazy)
if primaryKey:
print 'MAPPED PK:', table.columns.get(primaryKey)
mapper(tableClass, table, tableRelations, primary_key=table.columns.get(primaryKey))
else:
mapper(tableClass, table, tableRelations)
return table
finally:
self.lock.release()
def getMetadataTable(self, table):
return self.metadata.tables[table]
def openSession(self):
""" Open db session. """