diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 33e7cd2..bceda1c 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -12,8 +12,7 @@ Install the Wutta-COREPOS package to your virtual environment: pip install Wutta-COREPOS Edit your :term:`config file` to add CORE-POS DB connection info, and -related settings. Note that so far, only CORE Office DB connections -are supported. +related settings. .. code-block:: ini @@ -29,4 +28,14 @@ are supported. [corepos.db.office_arch] default.url = mysql+mysqlconnector://localhost/trans_archive + [corepos.db.lane_op] + keys = 01, 02 + 01.url = mysql+mysqlconnector://lane01/opdata + 02.url = mysql+mysqlconnector://lane02/opdata + + [corepos.db.lane_trans] + keys = 01, 02 + 01.url = mysql+mysqlconnector://lane01/translog + 02.url = mysql+mysqlconnector://lane02/translog + And that's it, the CORE-POS integration is configured. diff --git a/src/wutta_corepos/conf.py b/src/wutta_corepos/conf.py index 77bb6cc..7c3affb 100644 --- a/src/wutta_corepos/conf.py +++ b/src/wutta_corepos/conf.py @@ -74,6 +74,34 @@ class WuttaCoreposConfigExtension(WuttaConfigExtension): Dict of ``office_arch`` DB engines. May be empty if no config is found; otherwise there should at least be a ``default`` key defined, corresonding to :data:`core_office_arch_engine`. + + .. data:: core_lane_op_engine + + Primary engine for the ``lane_op`` DB. May be null if no + "default" engine is configured - which is *typical* for a + multi-lane environment. See :data:`core_lane_op_engines` for + the full set. + + .. data:: core_lane_op_engines + + Dict of ``lane_op`` DB engines. May be empty if no config is + found; otherwise keys are typically like ``01`` and ``02`` etc. + If present, the ``default`` key will correspond to + :data:`core_lane_op_engine`. + + .. data:: core_lane_trans_engine + + Primary engine for the ``lane_trans`` DB. May be null if no + "default" engine is configured - which is *typical* for a + multi-lane environment. See :data:`core_lane_trans_engines` + for the full set. + + .. data:: core_lane_trans_engines + + Dict of ``lane_trans`` DB engines. May be empty if no config + is found; otherwise keys are typically like ``01`` and ``02`` + etc. If present, the ``default`` key will correspond to + :data:`core_lane_trans_engine`. """ key = 'wutta_corepos' @@ -101,6 +129,20 @@ class WuttaCoreposConfigExtension(WuttaConfigExtension): config.core_office_arch_engine = engines.get('default') Session.configure(bind=config.core_office_arch_engine) + # lane_op + from corepos.db.lane_op import Session + engines = get_engines(config, 'corepos.db.lane_op') + config.core_lane_op_engines = engines + config.core_lane_op_engine = engines.get('default') + Session.configure(bind=config.core_lane_op_engine) + + # lane_trans + from corepos.db.lane_trans import Session + engines = get_engines(config, 'corepos.db.lane_trans') + config.core_lane_trans_engines = engines + config.core_lane_trans_engine = engines.get('default') + Session.configure(bind=config.core_lane_trans_engine) + # define some schema columns "late" unless not supported if config.get_bool('corepos.db.office_op.use_latest_columns', default=True, usedb=False): diff --git a/src/wutta_corepos/handler.py b/src/wutta_corepos/handler.py index 8b39795..6422f66 100644 --- a/src/wutta_corepos/handler.py +++ b/src/wutta_corepos/handler.py @@ -60,6 +60,24 @@ class CoreposHandler(GenericHandler): return model + def get_model_lane_op(self): + """ + Returns the :term:`data model` module for CORE Lane 'op' DB, + i.e. :mod:`pycorepos:corepos.db.lane_op.model`. + """ + from corepos.db.lane_op import model + + return model + + def get_model_lane_trans(self): + """ + Returns the :term:`data model` module for CORE Lane 'trans' + DB, i.e. :mod:`pycorepos:corepos.db.lane_trans.model`. + """ + from corepos.db.lane_trans import model + + return model + def make_session_office_op(self, dbkey='default', **kwargs): """ Make a new :term:`db session` for the CORE Office 'op' DB. @@ -99,6 +117,32 @@ class CoreposHandler(GenericHandler): kwargs['bind'] = self.config.core_office_arch_engines[dbkey] return Session(**kwargs) + def make_session_lane_op(self, dbkey='default', **kwargs): + """ + Make a new :term:`db session` for the CORE Lane 'op' DB. + + :returns: Instance of + :class:`pycorepos:corepos.db.lane_op.Session`. + """ + from corepos.db.lane_op import Session + + if 'bind' not in kwargs: + kwargs['bind'] = self.config.core_lane_op_engines[dbkey] + return Session(**kwargs) + + def make_session_lane_trans(self, dbkey='default', **kwargs): + """ + Make a new :term:`db session` for the CORE Lane 'trans' DB. + + :returns: Instance of + :class:`pycorepos:corepos.db.lane_trans.Session`. + """ + from corepos.db.lane_trans import Session + + if 'bind' not in kwargs: + kwargs['bind'] = self.config.core_lane_trans_engines[dbkey] + return Session(**kwargs) + def get_office_url(self, require=False): """ Returns the base URL for the CORE Office web app. diff --git a/src/wutta_corepos/web/db.py b/src/wutta_corepos/web/db.py index 7faeff2..4c9e292 100644 --- a/src/wutta_corepos/web/db.py +++ b/src/wutta_corepos/web/db.py @@ -49,6 +49,22 @@ in general. .. class:: ExtraCoreArchSessions Dict of secondary CORE Office 'arch' DB sessions, if applicable. + +.. class:: CoreLaneOpSession + + Primary web app :term:`db session` for CORE Lane 'op' DB. + +.. class:: CoreLaneTransSession + + Primary web app :term:`db session` for CORE Lane 'trans' DB. + +.. class:: ExtraCoreLaneOpSessions + + Dict of secondary CORE Lane 'op' DB sessions, if applicable. + +.. class:: ExtraCoreLaneTransSessions + + Dict of secondary CORE Lane 'trans' DB sessions, if applicable. """ from sqlalchemy.orm import sessionmaker, scoped_session @@ -64,7 +80,15 @@ register(CoreTransSession) CoreArchSession = scoped_session(sessionmaker()) register(CoreArchSession) +CoreLaneOpSession = scoped_session(sessionmaker()) +register(CoreLaneOpSession) + +CoreLaneTransSession = scoped_session(sessionmaker()) +register(CoreLaneTransSession) + # nb. these start out empty but may be populated on app startup ExtraCoreOpSessions = {} ExtraCoreTransSessions = {} ExtraCoreArchSessions = {} +ExtraCoreLaneOpSessions = {} +ExtraCoreLaneTransSessions = {} diff --git a/tests/test_conf.py b/tests/test_conf.py index c957dce..10f97a0 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -16,14 +16,21 @@ class TestWuttaCoreposConfigExtension(TestCase): self.assertFalse(hasattr(config, 'core_office_op_engine')) self.assertFalse(hasattr(config, 'core_office_trans_engine')) self.assertFalse(hasattr(config, 'core_office_arch_engine')) + self.assertFalse(hasattr(config, 'core_lane_op_engine')) + self.assertFalse(hasattr(config, 'core_lane_trans_engine')) ext = mod.WuttaCoreposConfigExtension() ext.configure(config) self.assertIsNone(config.core_office_op_engine) self.assertIsNone(config.core_office_trans_engine) self.assertIsNone(config.core_office_arch_engine) + self.assertIsNone(config.core_lane_op_engine) + self.assertIsNone(config.core_lane_trans_engine) # but config can change that config.setdefault('corepos.db.office_op.default.url', 'sqlite://') + config.setdefault('corepos.db.lane_trans.default.url', 'sqlite://') ext.configure(config) self.assertIsNotNone(config.core_office_op_engine) self.assertEqual(str(config.core_office_op_engine.url), 'sqlite://') + self.assertIsNotNone(config.core_lane_trans_engine) + self.assertEqual(str(config.core_lane_trans_engine.url), 'sqlite://') diff --git a/tests/test_handler.py b/tests/test_handler.py index 6dc5077..74f6f7b 100644 --- a/tests/test_handler.py +++ b/tests/test_handler.py @@ -34,6 +34,18 @@ class TestCoreposHandler(ConfigTestCase): arch_model = handler.get_model_office_arch() self.assertIs(arch_model, model) + def test_get_model_lane_op(self): + from corepos.db.lane_op import model + handler = self.make_handler() + op_model = handler.get_model_lane_op() + self.assertIs(op_model, model) + + def test_get_model_lane_trans(self): + from corepos.db.lane_trans import model + handler = self.make_handler() + trans_model = handler.get_model_lane_trans() + self.assertIs(trans_model, model) + def test_make_session_office_op(self): handler = self.make_handler() engine = sa.create_engine('sqlite://') @@ -61,6 +73,24 @@ class TestCoreposHandler(ConfigTestCase): self.assertIsInstance(arch_session, orm.Session) self.assertIs(arch_session.bind, engine) + def test_make_session_lane_op(self): + handler = self.make_handler() + engine = sa.create_engine('sqlite://') + with patch.object(self.config, 'core_lane_op_engines', create=True, + new={'default': engine}): + op_session = handler.make_session_lane_op() + self.assertIsInstance(op_session, orm.Session) + self.assertIs(op_session.bind, engine) + + def test_make_session_lane_trans(self): + handler = self.make_handler() + engine = sa.create_engine('sqlite://') + with patch.object(self.config, 'core_lane_trans_engines', create=True, + new={'default': engine}): + trans_session = handler.make_session_lane_trans() + self.assertIsInstance(trans_session, orm.Session) + self.assertIs(trans_session.bind, engine) + def test_get_office_url(self): handler = self.make_handler()