[stable-only] Re-add autocommit support

There are a number of projects that have yet to migrate away from
autocommit. To prevent them blocking the release, temporarily re-add
autocommit support. We do this only on the stable branch since we are
going to need to address SQLAlchemy 2.x support in C.

This is effectively a partial revert of change
Ifaca67c07f008d8bc0febeecd3e200cc7ee7a4b0 but focused solely on
autocommit and with additional logic in tests to prevent us trying to
use autocommit with SQLAlchemy 2.x (where it's not supported).

Change-Id: Ib49ed6886470284e6486581290af4e0f2482e5c5
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2023-09-18 10:05:25 +01:00
parent 683d989457
commit 115c3247b4
4 changed files with 49 additions and 3 deletions

View File

@ -176,6 +176,7 @@ class _TransactionFactory:
} }
self._maker_cfg = { self._maker_cfg = {
'expire_on_commit': _Default(False), 'expire_on_commit': _Default(False),
'__autocommit': _Default(False),
} }
self._transaction_ctx_cfg = { self._transaction_ctx_cfg = {
'rollback_reader_sessions': False, 'rollback_reader_sessions': False,
@ -446,6 +447,8 @@ class _TransactionFactory:
def _maker_args_for_conf(self, conf): def _maker_args_for_conf(self, conf):
maker_args = self._args_for_conf(self._maker_cfg, conf) maker_args = self._args_for_conf(self._maker_cfg, conf)
if '__autocommit' in maker_args:
maker_args['autocommit'] = maker_args.pop('__autocommit')
return maker_args return maker_args
def dispose_pool(self): def dispose_pool(self):
@ -1214,6 +1217,10 @@ class LegacyEngineFacade(object):
:param sqlite_fk: enable foreign keys in SQLite :param sqlite_fk: enable foreign keys in SQLite
:type sqlite_fk: bool :type sqlite_fk: bool
:param autocommit: use autocommit mode for created Session instances
(only supported with SQLAlchemy < 2.0)
:type autocommit: bool
:param expire_on_commit: expire session objects on commit :param expire_on_commit: expire session objects on commit
:type expire_on_commit: bool :type expire_on_commit: bool
@ -1251,7 +1258,8 @@ class LegacyEngineFacade(object):
""" """
def __init__(self, sql_connection, slave_connection=None, def __init__(self, sql_connection, slave_connection=None,
sqlite_fk=False, expire_on_commit=False, _conf=None, sqlite_fk=False, autocommit=False,
expire_on_commit=False, _conf=None,
_factory=None, **kwargs): _factory=None, **kwargs):
warnings.warn( warnings.warn(
"EngineFacade is deprecated; please use " "EngineFacade is deprecated; please use "
@ -1259,6 +1267,14 @@ class LegacyEngineFacade(object):
warning.OsloDBDeprecationWarning, warning.OsloDBDeprecationWarning,
stacklevel=2) stacklevel=2)
if autocommit is True:
warnings.warn(
'autocommit support has been removed in SQLAlchemy 2.0 and '
'should not be relied on; please rework your code to remove '
'reliance on this feature',
warning.OsloDBDeprecationWarning,
stacklevel=2)
if _factory: if _factory:
self._factory = _factory self._factory = _factory
else: else:
@ -1266,6 +1282,7 @@ class LegacyEngineFacade(object):
self._factory.configure( self._factory.configure(
sqlite_fk=sqlite_fk, sqlite_fk=sqlite_fk,
__autocommit=autocommit,
expire_on_commit=expire_on_commit, expire_on_commit=expire_on_commit,
**kwargs **kwargs
) )
@ -1331,7 +1348,7 @@ class LegacyEngineFacade(object):
@classmethod @classmethod
def from_config(cls, conf, def from_config(cls, conf,
sqlite_fk=False, expire_on_commit=False): sqlite_fk=False, autocommit=False, expire_on_commit=False):
"""Initialize EngineFacade using oslo.config config instance options. """Initialize EngineFacade using oslo.config config instance options.
:param conf: oslo.config config instance :param conf: oslo.config config instance
@ -1340,6 +1357,10 @@ class LegacyEngineFacade(object):
:param sqlite_fk: enable foreign keys in SQLite :param sqlite_fk: enable foreign keys in SQLite
:type sqlite_fk: bool :type sqlite_fk: bool
:param autocommit: use autocommit mode for created Session instances
(only supported with SQLAlchemy < 2.0)
:type autocommit: bool
:param expire_on_commit: expire session objects on commit :param expire_on_commit: expire session objects on commit
:type expire_on_commit: bool :type expire_on_commit: bool
@ -1348,4 +1369,5 @@ class LegacyEngineFacade(object):
return cls( return cls(
None, None,
sqlite_fk=sqlite_fk, sqlite_fk=sqlite_fk,
autocommit=autocommit,
expire_on_commit=expire_on_commit, _conf=conf) expire_on_commit=expire_on_commit, _conf=conf)

View File

@ -361,10 +361,12 @@ class MockFacadeTest(test_base.BaseTestCase):
maker_factories = mock.Mock(side_effect=get_maker) maker_factories = mock.Mock(side_effect=get_maker)
maker_factories( maker_factories(
autocommit=False,
engine=engines.writer, engine=engines.writer,
expire_on_commit=False) expire_on_commit=False)
if self.slave_uri: if self.slave_uri:
maker_factories( maker_factories(
autocommit=False,
engine=engines.async_reader, engine=engines.async_reader,
expire_on_commit=False) expire_on_commit=False)
@ -1385,6 +1387,19 @@ class PatchFactoryTest(test_base.BaseTestCase):
self.assertEqual(38, engine_args["max_overflow"]) self.assertEqual(38, engine_args["max_overflow"])
self.assertNotIn("mysql_wsrep_sync_wait", engine_args) self.assertNotIn("mysql_wsrep_sync_wait", engine_args)
def test_new_manager_deprecated_options(self):
normal_mgr = enginefacade.transaction_context()
normal_mgr.configure(
connection="sqlite://",
__autocommit=True,
)
normal_mgr._factory._start()
copied_mgr = normal_mgr.make_new_manager()
engine_args = copied_mgr._factory._maker_args_for_conf(None)
self.assertTrue(engine_args['autocommit'])
def test_new_manager_from_options(self): def test_new_manager_from_options(self):
"""test enginefacade's defaults given a default structure from opts""" """test enginefacade's defaults given a default structure from opts"""

View File

@ -432,7 +432,9 @@ class EngineFacadeTestCase(test_base.BaseTestCase):
logging_name=mock.ANY, logging_name=mock.ANY,
) )
get_maker.assert_called_once_with( get_maker.assert_called_once_with(
engine=create_engine(), expire_on_commit=True, engine=create_engine(),
autocommit=False,
expire_on_commit=True,
) )
def test_slave_connection(self): def test_slave_connection(self):

View File

@ -0,0 +1,7 @@
---
upgrade:
- |
The ability to create engine facades that used autocommit, which was
removed in 13.0.0, has been re-added temporarily to allow a longer
transition time for projects. It is still deprecated and requires
SQLAlchemy < 2.x. It will be removed again in a future release.