From a7eeac60cae28bb553327d317a88adb22c799ef3 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 2 Feb 2021 11:26:55 -0500 Subject: [PATCH] don't fail if purge recyclebin fails/mutex on registry the recyclebin purge is failing after SetInputSizesTest on occasion. try to reduce transaction overhead and don't error out if the purge fails. ensure _CONFIGURE_MUTEX is used when mutating or iterating the _mapper_registries collection. Change-Id: I9d9cd53b92419a2ad97bae5ee8bdd2657b6e408f --- lib/sqlalchemy/dialects/oracle/provision.py | 11 +++++++---- lib/sqlalchemy/orm/__init__.py | 4 +--- lib/sqlalchemy/orm/decl_api.py | 3 ++- lib/sqlalchemy/orm/mapper.py | 7 ++++--- test/dialect/oracle/test_types.py | 7 +++++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/sqlalchemy/dialects/oracle/provision.py b/lib/sqlalchemy/dialects/oracle/provision.py index e0dadd58ea..0a2c410099 100644 --- a/lib/sqlalchemy/dialects/oracle/provision.py +++ b/lib/sqlalchemy/dialects/oracle/provision.py @@ -60,10 +60,13 @@ def _oracle_drop_db(cfg, eng, ident): @stop_test_class_outside_fixtures.for_db("oracle") def stop_test_class_outside_fixtures(config, db, cls): - with db.begin() as conn: - # run magic command to get rid of identity sequences - # https://floo.bar/2019/11/29/drop-the-underlying-sequence-of-an-identity-column/ # noqa E501 - conn.exec_driver_sql("purge recyclebin") + try: + with db.begin() as conn: + # run magic command to get rid of identity sequences + # https://floo.bar/2019/11/29/drop-the-underlying-sequence-of-an-identity-column/ # noqa E501 + conn.exec_driver_sql("purge recyclebin") + except exc.DatabaseError as err: + log.warning("purge recyclebin command failed: %s", err) # clear statement cache on all connections that were used # https://github.com/oracle/python-cx_Oracle/issues/519 diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index ffbe785032..4793fc6386 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -268,9 +268,7 @@ def clear_mappers(): """ - with mapperlib._CONFIGURE_MUTEX: - all_regs = mapperlib._all_registries() - mapperlib._dispose_registries(all_regs, False) + mapperlib._dispose_registries(mapperlib._all_registries(), False) joinedload = strategy_options.joinedload._unbound_fn diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py index e6d41083f1..8afdb3a50b 100644 --- a/lib/sqlalchemy/orm/decl_api.py +++ b/lib/sqlalchemy/orm/decl_api.py @@ -469,7 +469,8 @@ class registry(object): self._new_mappers = False - mapperlib._mapper_registries[self] = True + with mapperlib._CONFIGURE_MUTEX: + mapperlib._mapper_registries[self] = True @property def mappers(self): diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 66c0627243..16a2c64160 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -62,11 +62,12 @@ _legacy_registry = None def _all_registries(): - return set(_mapper_registries) + with _CONFIGURE_MUTEX: + return set(_mapper_registries) def _unconfigured_mappers(): - for reg in _mapper_registries: + for reg in _all_registries(): for mapper in reg._mappers_to_configure(): yield mapper @@ -3347,7 +3348,7 @@ def configure_mappers(): """ - _configure_registries(set(_mapper_registries), cascade=True) + _configure_registries(_all_registries(), cascade=True) def _configure_registries(registries, cascade): diff --git a/test/dialect/oracle/test_types.py b/test/dialect/oracle/test_types.py index 3636dad13f..45a0fd4375 100644 --- a/test/dialect/oracle/test_types.py +++ b/test/dialect/oracle/test_types.py @@ -1199,7 +1199,6 @@ class SetInputSizesTest(fixtures.TestBase): "t2", m, Column("foo", NullType().with_variant(datatype, "oracle")) ) t3 = Table("t3", m, Column("foo", TestTypeDec())) - m.create_all(testing.db) class CursorWrapper(object): # cx_oracle cursor can't be modified so we have to @@ -1222,7 +1221,11 @@ class SetInputSizesTest(fixtures.TestBase): else: engine = testing.db - with engine.begin() as conn: + with engine.connect() as conn: + conn.begin() + + m.create_all(conn, checkfirst=False) + connection_fairy = conn.connection for tab in [t1, t2, t3]: with mock.patch.object( -- 2.47.2