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?
This commit is contained in:
Lance Edgar 2023-02-07 12:20:22 -06:00
parent 9263dd4ddb
commit 5f70a524e9
2 changed files with 63 additions and 24 deletions

View file

@ -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
]

View file

@ -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)