From 5f70a524e981e8f0192bc57ceed809634ce3974a Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 7 Feb 2023 12:20:22 -0600 Subject: [PATCH] Use latest zope.sqlalchemy package session / transaction registration modified per upstream changes, but previous logic kept to support older versions of zope.sqlalchemy - for now, although probably should require minimum version soon? --- setup.py | 6 +--- tailbone/db.py | 81 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/setup.py b/setup.py index 107f051a..1930f2cd 100644 --- a/setup.py +++ b/setup.py @@ -62,11 +62,6 @@ requires = [ # # package # low high - # TODO: previously was capping this to pre-1.0 although i'm not sure why. - # however the 1.2 release has some breaking changes which require refactor. - # cf. https://pypi.org/project/zope.sqlalchemy/#id3 - 'zope.sqlalchemy<1.2', # 0.7 1.1 - # TODO: apparently they jumped from 0.1 to 0.9 and that broke us... # (0.1 was released on 2014-09-14 and then 0.9 came out on 2018-09-27) # (i've cached 0.1 at pypi.rattailproject.org just in case it disappears) @@ -106,6 +101,7 @@ requires = [ 'waitress', # 0.8.1 'WebHelpers2', # 2.0 'WTForms', # 2.1 + 'zope.sqlalchemy', # 0.7 2.0 ] diff --git a/tailbone/db.py b/tailbone/db.py index ae919e49..4a6821f9 100644 --- a/tailbone/db.py +++ b/tailbone/db.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2023 Lance Edgar # # This file is part of Rattail. # @@ -24,8 +24,6 @@ Database Stuff """ -from __future__ import unicode_literals, absolute_import - import sqlalchemy as sa from zope.sqlalchemy import datamanager import sqlalchemy_continuum as continuum @@ -111,20 +109,51 @@ def join_transaction(session, initial_state=datamanager.STATUS_ACTIVE, transacti DataManager(session, initial_state, transaction_manager, keep_session=keep_session) -class ZopeTransactionExtension(datamanager.ZopeTransactionExtension): - """Record that a flush has occurred on a session's connection. This allows - the DataManager to rollback rather than commit on read only transactions. +if zope_sqlalchemy_version_parsed >= parse_version('1.2'): # 1.2+ - .. note:: - This class is copied from upstream, and tweaked so that our custom - :func:`join_transaction()` will be used. - """ + class ZopeTransactionEvents(datamanager.ZopeTransactionEvents): + """ + Record that a flush has occurred on a session's + connection. This allows the DataManager to rollback rather + than commit on read only transactions. - def after_begin(self, session, transaction, connection): - join_transaction(session, self.initial_state, self.transaction_manager, self.keep_session) + .. note:: + This class is copied from upstream, and tweaked so that our + custom :func:`join_transaction()` will be used. + """ - def after_attach(self, session, instance): - join_transaction(session, self.initial_state, self.transaction_manager, self.keep_session) + def after_begin(self, session, transaction, connection): + join_transaction(session, self.initial_state, + self.transaction_manager, self.keep_session) + + def after_attach(self, session, instance): + join_transaction(session, self.initial_state, + self.transaction_manager, self.keep_session) + + def join_transaction(self, session): + join_transaction(session, self.initial_state, + self.transaction_manager, self.keep_session) + +else: # pre-1.2 + + class ZopeTransactionExtension(datamanager.ZopeTransactionExtension): + """ + Record that a flush has occurred on a session's + connection. This allows the DataManager to rollback rather + than commit on read only transactions. + + .. note:: + This class is copied from upstream, and tweaked so that our + custom :func:`join_transaction()` will be used. + """ + + def after_begin(self, session, transaction, connection): + join_transaction(session, self.initial_state, + self.transaction_manager, self.keep_session) + + def after_attach(self, session, instance): + join_transaction(session, self.initial_state, + self.transaction_manager, self.keep_session) def register(session, initial_state=datamanager.STATUS_ACTIVE, @@ -147,11 +176,21 @@ def register(session, initial_state=datamanager.STATUS_ACTIVE, """ from sqlalchemy import event - ext = ZopeTransactionExtension( - initial_state=initial_state, - transaction_manager=transaction_manager, - keep_session=keep_session, - ) + if zope_sqlalchemy_version_parsed >= parse_version('1.2'): # 1.2+ + + ext = ZopeTransactionEvents( + initial_state=initial_state, + transaction_manager=transaction_manager, + keep_session=keep_session, + ) + + else: # pre-1.2 + + ext = ZopeTransactionExtension( + initial_state=initial_state, + transaction_manager=transaction_manager, + keep_session=keep_session, + ) event.listen(session, "after_begin", ext.after_begin) event.listen(session, "after_attach", ext.after_attach) @@ -160,6 +199,10 @@ def register(session, initial_state=datamanager.STATUS_ACTIVE, event.listen(session, "after_bulk_delete", ext.after_bulk_delete) event.listen(session, "before_commit", ext.before_commit) + if zope_sqlalchemy_version_parsed >= parse_version('1.5'): # 1.5+ + if datamanager.SA_GE_14: + event.listen(session, "do_orm_execute", ext.do_orm_execute) + register(Session) register(TempmonSession)