diff --git a/src/python/dm/aps_user_db/__init__.py b/src/python/dm/aps_user_db/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/python/dm/aps_user_db/api/__init__.py b/src/python/dm/aps_user_db/api/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/python/dm/aps_user_db/api/apsUserDbApi.py b/src/python/dm/aps_user_db/api/apsUserDbApi.py
new file mode 100755
index 0000000000000000000000000000000000000000..e9a2edeeebbfbbcfb66f1b1d7e1887b0e83a6528
--- /dev/null
+++ b/src/python/dm/aps_user_db/api/apsUserDbApi.py
@@ -0,0 +1,33 @@
+#!/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)
+
+
diff --git a/src/python/dm/aps_user_db/api/apsUserDbApiBase.py b/src/python/dm/aps_user_db/api/apsUserDbApiBase.py
new file mode 100755
index 0000000000000000000000000000000000000000..ec0bbaf5c7b3db83511f274b2aac15dfc04e8136
--- /dev/null
+++ b/src/python/dm/aps_user_db/api/apsUserDbApiBase.py
@@ -0,0 +1,109 @@
+#!/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()
+
+
diff --git a/src/python/dm/aps_user_db/entities/__init__.py b/src/python/dm/aps_user_db/entities/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/python/dm/aps_user_db/entities/apsUserDbEntityMap.py b/src/python/dm/aps_user_db/entities/apsUserDbEntityMap.py
new file mode 100755
index 0000000000000000000000000000000000000000..3fe8fbb3cf04896e41e95403e51b0dbfc520d87f
--- /dev/null
+++ b/src/python/dm/aps_user_db/entities/apsUserDbEntityMap.py
@@ -0,0 +1,10 @@
+#!/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'}}), 
+}
+
diff --git a/src/python/dm/aps_user_db/entities/apsUserInfo.py b/src/python/dm/aps_user_db/entities/apsUserInfo.py
new file mode 100755
index 0000000000000000000000000000000000000000..3a82a9df451534405a994e9e97c930a0c25cab75
--- /dev/null
+++ b/src/python/dm/aps_user_db/entities/apsUserInfo.py
@@ -0,0 +1,23 @@
+#!/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)
+
+
+
diff --git a/src/python/dm/aps_user_db/impl/__init__.py b/src/python/dm/aps_user_db/impl/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/python/dm/aps_user_db/impl/apsUserDbManager.py b/src/python/dm/aps_user_db/impl/apsUserDbManager.py
new file mode 100755
index 0000000000000000000000000000000000000000..1f7d169456ab5727fb1c8f0a393b4bc8ad710c14
--- /dev/null
+++ b/src/python/dm/aps_user_db/impl/apsUserDbManager.py
@@ -0,0 +1,199 @@
+#!/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'
+
+
diff --git a/src/python/dm/aps_user_db/impl/apsUserInfoHandler.py b/src/python/dm/aps_user_db/impl/apsUserInfoHandler.py
new file mode 100755
index 0000000000000000000000000000000000000000..68d9606543db7fabd3e86547af6b27307ba98fcd
--- /dev/null
+++ b/src/python/dm/aps_user_db/impl/apsUserInfoHandler.py
@@ -0,0 +1,27 @@
+#!/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))
+
diff --git a/src/python/dm/aps_user_db/impl/oracleDbManager.py.working b/src/python/dm/aps_user_db/impl/oracleDbManager.py.working
new file mode 100755
index 0000000000000000000000000000000000000000..2dc35ae753287b3a0d1bcdc577ec150df38228e6
--- /dev/null
+++ b/src/python/dm/aps_user_db/impl/oracleDbManager.py.working
@@ -0,0 +1,222 @@
+#!/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. """
+        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 = OracleDbManager.getInstance()
+    mgr.acquireConnection()
+    mgr.inspectTables()
+    mgr.inspectTables2()
+    print 'Got connection'
+    from oracleUserInfoHandler import OracleUserInfoHandler
+    handler = OracleUserInfoHandler()
+    session = mgr.openSession()
+    users = handler.getUsers(session)
+    for u in users:
+        print u.badge_no, u.last_name
+
+
diff --git a/src/python/dm/common/objects/apsUserInfo.py b/src/python/dm/common/objects/apsUserInfo.py
new file mode 100755
index 0000000000000000000000000000000000000000..832288759fb74a176bafc2b03f44ac877c0222d2
--- /dev/null
+++ b/src/python/dm/common/objects/apsUserInfo.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+from dmObject import DmObject
+
+class ApsUserInfo(DmObject):
+
+    DEFAULT_KEY_LIST = [ 'id', 'badgeNumber', 'firstName', 'middleName', 'lastName', 'email' ]
+
+    def __init__(self, dict):
+        DmObject.__init__(self, dict)
+