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 sqlalchemy as sa
from sqlalchemy.orm import sessionmaker, scoped_session
from rattail.config import make_config
from rattail.exceptions import ConfigurationError
@ -37,6 +38,7 @@ from rattail.db.types import GPCType
from pyramid.config import Configurator
from pyramid.authentication import SessionAuthenticationPolicy
from zope.sqlalchemy import register
import tailbone.db
from tailbone.auth import TailboneAuthorizationPolicy
@ -69,6 +71,13 @@ def make_rattail_config(settings):
if hasattr(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
# unnecessary connections (and pooling limits).
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())
TrainwreckSession = scoped_session(sessionmaker())
# empty dict for now, this must populated on app startup (if needed)
ExtraTrainwreckSessions = {}
class TailboneSessionDataManager(datamanager.SessionDataManager):
"""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
supports_multiple_engines = False
engine_type_key = 'rattail'
SessionDefault = None
SessionExtras = {}
row_attrs = {}
cell_attrs = {}
@ -172,9 +174,16 @@ class MasterView(View):
@property
def Session(self):
"""
SQLAlchemy scoped session to use when querying the database. Defaults
to ``tailbone.db.Session``.
Which session we return may depend on user's "current" engine.
"""
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
return Session

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar
# Copyright © 2010-2019 Lance Edgar
#
# This file is part of Rattail.
#
@ -29,8 +29,9 @@ from __future__ import unicode_literals, absolute_import
import six
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
@ -38,7 +39,6 @@ class TransactionView(MasterView):
"""
Master view for Trainwreck transactions
"""
Session = TrainwreckSession
# model_class = trainwreck.Transaction
model_title = "Trainwreck Transaction"
model_title_plural = "Trainwreck Transactions"
@ -48,6 +48,11 @@ class TransactionView(MasterView):
editable = False
deletable = False
supports_multiple_engines = True
engine_type_key = 'trainwreck'
SessionDefault = TrainwreckSession
SessionExtras = ExtraTrainwreckSessions
labels = {
'cashback': "Cash Back",
}
@ -125,6 +130,15 @@ class TransactionView(MasterView):
'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):
super(TransactionView, self).configure_grid(g)
g.filters['receipt_number'].default_active = True