Skip to content

Commit

Permalink
Add standalone orm.close_all method and deprecate SessionMaker.close_all
Browse files Browse the repository at this point in the history
Added a new function :func:`.close_all_sessions` which takes
over the task of the :meth:`.Session.close_all` method, which
is now deprecated as this is confusing as a classmethod.
Pull request courtesy Augustin Trancart.

Fixes: #4412

Closes: #4438
Pull-request: #4438
Pull-request-sha: 7833d12

Change-Id: Ib35eaa520ae886f3f8f550f9712fc3b139e00b60
  • Loading branch information
autra authored and zzzeek committed Jan 12, 2019
1 parent 55f930e commit 8fac612
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 9 deletions.
8 changes: 8 additions & 0 deletions doc/build/changelog/unreleased_13/4412.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. change::
:tags: change, orm
:tickets: 4412

Added a new function :func:`.close_all_sessions` which takes
over the task of the :meth:`.Session.close_all` method, which
is now deprecated as this is confusing as a classmethod.
Pull request courtesy Augustin Trancart.
2 changes: 2 additions & 0 deletions doc/build/orm/session_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Session and sessionmaker()
Session Utilities
-----------------

.. autofunction:: close_all_sessions

.. autofunction:: make_transient

.. autofunction:: make_transient_to_detached
Expand Down
1 change: 1 addition & 0 deletions lib/sqlalchemy/orm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from .relationships import RelationshipProperty # noqa
from .relationships import remote # noqa
from .scoping import scoped_session # noqa
from .session import close_all_sessions # noqa
from .session import make_transient # noqa
from .session import make_transient_to_detached # noqa
from .session import object_session # noqa
Expand Down
27 changes: 25 additions & 2 deletions lib/sqlalchemy/orm/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,16 @@ class _SessionClassMethods(object):
"""Class-level methods for :class:`.Session`, :class:`.sessionmaker`."""

@classmethod
@util.deprecated(
"1.3",
"The :meth:`.Session.close_all` method is deprecated and will be "
"removed in a future release. Please refer to "
":func:`.session.close_all_sessions`.",
)
def close_all(cls):
"""Close *all* sessions in memory."""

for sess in _sessions.values():
sess.close()
close_all_sessions()

@classmethod
@util.dependencies("sqlalchemy.orm.util")
Expand Down Expand Up @@ -3204,6 +3209,24 @@ def __repr__(self):
)


def close_all_sessions():
"""Close all sessions in memory.
This function consults a global registry of all :class:`.Session` objects
and calls :meth:`.Session.close` on them, which resets them to a clean
state.
This function is not for general use but may be useful for test suites
within the teardown scheme.
.. versionadded:: 1.3
"""

for sess in _sessions.values():
sess.close()


def make_transient(instance):
"""Alter the state of the given instance so that it is :term:`transient`.
Expand Down
4 changes: 2 additions & 2 deletions lib/sqlalchemy/testing/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def teardown(self):
class _ORMTest(object):
@classmethod
def teardown_class(cls):
sa.orm.session.Session.close_all()
sa.orm.session.close_all_sessions()
sa.orm.clear_mappers()


Expand Down Expand Up @@ -287,7 +287,7 @@ def setup(self):
self._setup_each_inserts()

def teardown(self):
sa.orm.session.Session.close_all()
sa.orm.session.close_all_sessions()
self._teardown_each_mappers()
self._teardown_each_classes()
self._teardown_each_tables()
Expand Down
3 changes: 2 additions & 1 deletion test/ext/declarative/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from sqlalchemy.orm import backref
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm import clear_mappers
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import column_property
from sqlalchemy.orm import composite
from sqlalchemy.orm import configure_mappers
Expand Down Expand Up @@ -60,7 +61,7 @@ def setup(self):
Base = decl.declarative_base(testing.db)

def teardown(self):
Session.close_all()
close_all_sessions()
clear_mappers()
Base.metadata.drop_all()

Expand Down
3 changes: 2 additions & 1 deletion test/ext/declarative/test_inheritance.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.ext.declarative import has_inherited_table
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm import clear_mappers
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import configure_mappers
from sqlalchemy.orm import create_session
from sqlalchemy.orm import deferred
Expand Down Expand Up @@ -39,7 +40,7 @@ def setup(self):
Base = decl.declarative_base(testing.db)

def teardown(self):
Session.close_all()
close_all_sessions()
clear_mappers()
Base.metadata.drop_all()

Expand Down
3 changes: 2 additions & 1 deletion test/ext/declarative/test_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from sqlalchemy.orm import base as orm_base
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm import clear_mappers
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import column_property
from sqlalchemy.orm import configure_mappers
from sqlalchemy.orm import create_session
Expand Down Expand Up @@ -41,7 +42,7 @@ def setup(self):
Base = decl.declarative_base(testing.db)

def teardown(self):
Session.close_all()
close_all_sessions()
clear_mappers()
Base.metadata.drop_all()

Expand Down
3 changes: 2 additions & 1 deletion test/orm/test_eager_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from sqlalchemy import text
from sqlalchemy.orm import aliased
from sqlalchemy.orm import backref
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import column_property
from sqlalchemy.orm import contains_eager
from sqlalchemy.orm import create_session
Expand Down Expand Up @@ -5054,7 +5055,7 @@ def test_integrate(self):
session.add_all([rscott, alien, brunner])
session.commit()

session.close_all()
close_all_sessions()
self.d = session.query(Director).options(joinedload("*")).first()
assert len(list(session)) == 3

Expand Down
46 changes: 46 additions & 0 deletions test/orm/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from sqlalchemy import testing
from sqlalchemy.orm import attributes
from sqlalchemy.orm import backref
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import create_session
from sqlalchemy.orm import exc as orm_exc
from sqlalchemy.orm import joinedload
Expand Down Expand Up @@ -148,6 +149,51 @@ def test_transaction(self):
class SessionUtilTest(_fixtures.FixtureTest):
run_inserts = None

def test_close_all_sessions(self):
users, User = self.tables.users, self.classes.User

mapper(User, users)

s1 = Session()
u1 = User()
s1.add(u1)

s2 = Session()
u2 = User()
s2.add(u2)

assert u1 in s1
assert u2 in s2

close_all_sessions()

assert u1 not in s1
assert u2 not in s2

def test_session_close_all_deprecated(self):
users, User = self.tables.users, self.classes.User

mapper(User, users)

s1 = Session()
u1 = User()
s1.add(u1)

s2 = Session()
u2 = User()
s2.add(u2)

assert u1 in s1
assert u2 in s2

with assertions.expect_deprecated(
r"The Session.close_all\(\) method is deprecated and will "
"be removed in a future release. "):
Session.close_all()

assert u1 not in s1
assert u2 not in s2

def test_object_session_raises(self):
User = self.classes.User

Expand Down
3 changes: 2 additions & 1 deletion test/orm/test_subquery_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from sqlalchemy import testing
from sqlalchemy.orm import aliased
from sqlalchemy.orm import clear_mappers
from sqlalchemy.orm import close_all_sessions
from sqlalchemy.orm import create_session
from sqlalchemy.orm import deferred
from sqlalchemy.orm import joinedload
Expand Down Expand Up @@ -2666,7 +2667,7 @@ def test_integrate(self):
session.add_all([rscott, alien, brunner])
session.commit()

session.close_all()
close_all_sessions()
d = session.query(Director).options(subqueryload("*")).first()
assert len(list(session)) == 3

Expand Down

0 comments on commit 8fac612

Please sign in to comment.