diff options
author | mike bayer <mike_mp@zzzcomputing.com> | 2022-12-05 14:01:12 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2022-12-05 14:01:12 +0000 |
commit | 9058593e0b28cee0211251de6604e4601ff69a00 (patch) | |
tree | fc39fa7fc6ef9bf4beb44dbfec4674d68a2c9464 | |
parent | 3497fd1c5b60ac529450fb2aab7c7fbb8da8a9e4 (diff) | |
parent | ca46caede4b8d846f3cd48e642922ae821d0be2b (diff) | |
download | sqlalchemy-9058593e0b28cee0211251de6604e4601ff69a00.tar.gz |
Merge "adjustments for unreliable gc" into main
-rw-r--r-- | doc/build/orm/queryguide/_deferred_setup.rst | 1 | ||||
-rw-r--r-- | doc/build/orm/queryguide/select.rst | 4 | ||||
-rw-r--r-- | test/aaa_profiling/test_memusage.py | 54 | ||||
-rw-r--r-- | test/orm/test_transaction.py | 39 | ||||
-rw-r--r-- | test/requirements.py | 1 |
5 files changed, 60 insertions, 39 deletions
diff --git a/doc/build/orm/queryguide/_deferred_setup.rst b/doc/build/orm/queryguide/_deferred_setup.rst index e75630c46..2675c9341 100644 --- a/doc/build/orm/queryguide/_deferred_setup.rst +++ b/doc/build/orm/queryguide/_deferred_setup.rst @@ -100,5 +100,6 @@ This page illustrates the mappings and fixture data used by the ... ) >>> session.commit() BEGIN ... COMMIT + >>> session.close() >>> conn.begin() BEGIN ... diff --git a/doc/build/orm/queryguide/select.rst b/doc/build/orm/queryguide/select.rst index 7967bb4d5..55c3ae94e 100644 --- a/doc/build/orm/queryguide/select.rst +++ b/doc/build/orm/queryguide/select.rst @@ -1001,6 +1001,10 @@ which belonged to "sandy": Relationship Instance Comparison Operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. comment + + >>> session.expunge_all() + The :func:`_orm.relationship`-bound attribute also offers a few SQL construction implementations that are geared towards filtering a :func:`_orm.relationship`-bound attribute in terms of a specific instance of a related object, which can unpack diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py index 1162a54af..4756a3fd5 100644 --- a/test/aaa_profiling/test_memusage.py +++ b/test/aaa_profiling/test_memusage.py @@ -18,6 +18,7 @@ from sqlalchemy import util from sqlalchemy.engine import result from sqlalchemy.engine.processors import to_decimal_processor_factory from sqlalchemy.orm import aliased +from sqlalchemy.orm import attributes from sqlalchemy.orm import clear_mappers from sqlalchemy.orm import configure_mappers from sqlalchemy.orm import declarative_base @@ -1724,3 +1725,56 @@ class CycleTest(_fixtures.FixtureTest): s.close() go() + + +@testing.add_to_marker.memory_intensive +class MiscMemoryIntensiveTests(fixtures.TestBase): + @testing.fixture + def user_fixture(self, decl_base): + class User(decl_base): + __tablename__ = "user" + + id = Column(Integer, primary_key=True) + name = Column(String(50)) + + decl_base.metadata.create_all(testing.db) + yield User + + @testing.requires.predictable_gc + def test_gced_delete_on_rollback(self, user_fixture): + User = user_fixture + + s = fixture_session() + u1 = User(name="ed") + s.add(u1) + s.commit() + + s.delete(u1) + u1_state = attributes.instance_state(u1) + assert u1_state in s.identity_map.all_states() + assert u1_state in s._deleted + s.flush() + assert u1_state not in s.identity_map.all_states() + assert u1_state not in s._deleted + del u1 + gc_collect() + gc_collect() + gc_collect() + assert u1_state.obj() is None + + s.rollback() + # new in 1.1, not in identity map if the object was + # gc'ed and we restore snapshot; we've changed update_impl + # to just skip this object + assert u1_state not in s.identity_map.all_states() + + # in any version, the state is replaced by the query + # because the identity map would switch it + u1 = s.query(User).filter_by(name="ed").one() + assert u1_state not in s.identity_map.all_states() + + eq_(s.scalar(select(func.count("*")).select_from(User.__table__)), 1) + s.delete(u1) + s.flush() + eq_(s.scalar(select(func.count("*")).select_from(User.__table__)), 0) + s.commit() diff --git a/test/orm/test_transaction.py b/test/orm/test_transaction.py index 2f08080ad..f66908fc9 100644 --- a/test/orm/test_transaction.py +++ b/test/orm/test_transaction.py @@ -1249,45 +1249,6 @@ class AutoExpireTest(_LocalFixture): assert u1 in s assert u1 not in s.deleted - @testing.requires.predictable_gc - def test_gced_delete_on_rollback(self): - User, users = self.classes.User, self.tables.users - - s = fixture_session() - u1 = User(name="ed") - s.add(u1) - s.commit() - - s.delete(u1) - u1_state = attributes.instance_state(u1) - assert u1_state in s.identity_map.all_states() - assert u1_state in s._deleted - s.flush() - assert u1_state not in s.identity_map.all_states() - assert u1_state not in s._deleted - del u1 - gc_collect() - gc_collect() - gc_collect() - assert u1_state.obj() is None - - s.rollback() - # new in 1.1, not in identity map if the object was - # gc'ed and we restore snapshot; we've changed update_impl - # to just skip this object - assert u1_state not in s.identity_map.all_states() - - # in any version, the state is replaced by the query - # because the identity map would switch it - u1 = s.query(User).filter_by(name="ed").one() - assert u1_state not in s.identity_map.all_states() - - eq_(s.scalar(select(func.count("*")).select_from(users)), 1) - s.delete(u1) - s.flush() - eq_(s.scalar(select(func.count("*")).select_from(users)), 0) - s.commit() - def test_trans_deleted_cleared_on_rollback(self): User = self.classes.User s = fixture_session() diff --git a/test/requirements.py b/test/requirements.py index e56c944ff..5276593c9 100644 --- a/test/requirements.py +++ b/test/requirements.py @@ -397,6 +397,7 @@ class DefaultRequirements(SuiteRequirements): [ no_support("oracle", "Oracle XE usually can't handle these"), no_support("mssql+pyodbc", "MS ODBC drivers struggle"), + no_support("+aiosqlite", "very unreliable driver"), self._running_on_windows(), ] ) |