Add "multi-engine" support for Trainwreck transaction views

This commit is contained in:
Lance Edgar 2019-07-25 15:40:38 -05:00
parent b07365b487
commit e756ae3c8f
4 changed files with 40 additions and 5 deletions

View file

@ -30,6 +30,7 @@ import os
import warnings import warnings
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker, scoped_session
from rattail.config import make_config from rattail.config import make_config
from rattail.exceptions import ConfigurationError from rattail.exceptions import ConfigurationError
@ -37,6 +38,7 @@ from rattail.db.types import GPCType
from pyramid.config import Configurator from pyramid.config import Configurator
from pyramid.authentication import SessionAuthenticationPolicy from pyramid.authentication import SessionAuthenticationPolicy
from zope.sqlalchemy import register
import tailbone.db import tailbone.db
from tailbone.auth import TailboneAuthorizationPolicy from tailbone.auth import TailboneAuthorizationPolicy
@ -69,6 +71,13 @@ def make_rattail_config(settings):
if hasattr(rattail_config, 'tempmon_engine'): if hasattr(rattail_config, 'tempmon_engine'):
tailbone.db.TempmonSession.configure(bind=rattail_config.tempmon_engine) tailbone.db.TempmonSession.configure(bind=rattail_config.tempmon_engine)
# create session wrappers for each "extra" Trainwreck engine
for key, engine in rattail_config.trainwreck_engines.items():
if key != 'default':
Session = scoped_session(sessionmaker(bind=engine))
register(Session)
tailbone.db.ExtraTrainwreckSessions[key] = Session
# Make sure rattail config object uses our scoped session, to avoid # Make sure rattail config object uses our scoped session, to avoid
# unnecessary connections (and pooling limits). # unnecessary connections (and pooling limits).
rattail_config._session_factory = lambda: (tailbone.db.Session(), False) rattail_config._session_factory = lambda: (tailbone.db.Session(), False)

View file

@ -41,6 +41,9 @@ Session = scoped_session(sessionmaker(class_=SessionBase, rattail_config=None, r
TempmonSession = scoped_session(sessionmaker()) TempmonSession = scoped_session(sessionmaker())
TrainwreckSession = scoped_session(sessionmaker()) TrainwreckSession = scoped_session(sessionmaker())
# empty dict for now, this must populated on app startup (if needed)
ExtraTrainwreckSessions = {}
class TailboneSessionDataManager(datamanager.SessionDataManager): class TailboneSessionDataManager(datamanager.SessionDataManager):
"""Integrate a top level sqlalchemy session transaction into a zope transaction """Integrate a top level sqlalchemy session transaction into a zope transaction

View file

@ -130,6 +130,8 @@ class MasterView(View):
# other things also, to get a DB picker in the header for all views # other things also, to get a DB picker in the header for all views
supports_multiple_engines = False supports_multiple_engines = False
engine_type_key = 'rattail' engine_type_key = 'rattail'
SessionDefault = None
SessionExtras = {}
row_attrs = {} row_attrs = {}
cell_attrs = {} cell_attrs = {}
@ -172,9 +174,16 @@ class MasterView(View):
@property @property
def Session(self): def Session(self):
""" """
SQLAlchemy scoped session to use when querying the database. Defaults Which session we return may depend on user's "current" engine.
to ``tailbone.db.Session``.
""" """
if self.supports_multiple_engines:
dbkey = self.get_current_engine_dbkey()
if dbkey != 'default' and dbkey in self.SessionExtras:
return self.SessionExtras[dbkey]
if self.SessionDefault:
return self.SessionDefault
from tailbone.db import Session from tailbone.db import Session
return Session return Session

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2019 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -29,8 +29,9 @@ from __future__ import unicode_literals, absolute_import
import six import six
from rattail.time import localtime from rattail.time import localtime
from rattail.util import OrderedDict
from tailbone.db import TrainwreckSession from tailbone.db import TrainwreckSession, ExtraTrainwreckSessions
from tailbone.views import MasterView from tailbone.views import MasterView
@ -38,7 +39,6 @@ class TransactionView(MasterView):
""" """
Master view for Trainwreck transactions Master view for Trainwreck transactions
""" """
Session = TrainwreckSession
# model_class = trainwreck.Transaction # model_class = trainwreck.Transaction
model_title = "Trainwreck Transaction" model_title = "Trainwreck Transaction"
model_title_plural = "Trainwreck Transactions" model_title_plural = "Trainwreck Transactions"
@ -48,6 +48,11 @@ class TransactionView(MasterView):
editable = False editable = False
deletable = False deletable = False
supports_multiple_engines = True
engine_type_key = 'trainwreck'
SessionDefault = TrainwreckSession
SessionExtras = ExtraTrainwreckSessions
labels = { labels = {
'cashback': "Cash Back", 'cashback': "Cash Back",
} }
@ -125,6 +130,15 @@ class TransactionView(MasterView):
'void', 'void',
] ]
def get_db_engines(self):
engines = OrderedDict()
if self.rattail_config.trainwreck_engine:
engines['default'] = self.rattail_config.trainwreck_engine
for dbkey in sorted(self.rattail_config.trainwreck_engines):
if dbkey != 'default':
engines[dbkey] = self.rattail_config.trainwreck_engines[dbkey]
return engines
def configure_grid(self, g): def configure_grid(self, g):
super(TransactionView, self).configure_grid(g) super(TransactionView, self).configure_grid(g)
g.filters['receipt_number'].default_active = True g.filters['receipt_number'].default_active = True