summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/scoping.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-10-08 15:20:48 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-10-10 01:17:25 -0400
commit2665a0c4cb3e94e6545d0b9bbcbcc39ccffebaba (patch)
treeed25383ce7e5899d7d643a11df0f8aee9f2ab959 /lib/sqlalchemy/orm/scoping.py
parentbcc17b1d6e2cac3b0e45c0b17a62cf2d5fc5c5ab (diff)
downloadsqlalchemy-2665a0c4cb3e94e6545d0b9bbcbcc39ccffebaba.tar.gz
generalize scoped_session proxying and apply to asyncio elements
Reworked the proxy creation used by scoped_session() to be based on fully copied code with augmented docstrings and moved it into langhelpers. asyncio session, engine, connection can now take advantage of it so that all non-async methods are availble. Overall implementation of most important accessors / methods on AsyncConnection, etc. , including awaitable versions of invalidate, execution_options, etc. In order to support an event dispatcher on the async classes while still allowing them to hold __slots__, make some adjustments to the event system to allow that to be present, at least rudimentally. Fixes: #5628 Change-Id: I5eb6929fc1e4fdac99e4b767dcfd49672d56e2b2
Diffstat (limited to 'lib/sqlalchemy/orm/scoping.py')
-rw-r--r--lib/sqlalchemy/orm/scoping.py99
1 files changed, 51 insertions, 48 deletions
diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py
index 1090501ca..29d845c0a 100644
--- a/lib/sqlalchemy/orm/scoping.py
+++ b/lib/sqlalchemy/orm/scoping.py
@@ -9,14 +9,60 @@ from . import class_mapper
from . import exc as orm_exc
from .session import Session
from .. import exc as sa_exc
+from ..util import create_proxy_methods
from ..util import ScopedRegistry
from ..util import ThreadLocalRegistry
from ..util import warn
-
__all__ = ["scoped_session"]
+@create_proxy_methods(
+ Session,
+ ":class:`_orm.Session`",
+ ":class:`_orm.scoping.scoped_session`",
+ classmethods=["close_all", "object_session", "identity_key"],
+ methods=[
+ "__contains__",
+ "__iter__",
+ "add",
+ "add_all",
+ "begin",
+ "begin_nested",
+ "close",
+ "commit",
+ "connection",
+ "delete",
+ "execute",
+ "expire",
+ "expire_all",
+ "expunge",
+ "expunge_all",
+ "flush",
+ "get_bind",
+ "is_modified",
+ "bulk_save_objects",
+ "bulk_insert_mappings",
+ "bulk_update_mappings",
+ "merge",
+ "query",
+ "refresh",
+ "rollback",
+ "scalar",
+ ],
+ attributes=[
+ "bind",
+ "dirty",
+ "deleted",
+ "new",
+ "identity_map",
+ "is_active",
+ "autoflush",
+ "no_autoflush",
+ "info",
+ "autocommit",
+ ],
+)
class scoped_session(object):
"""Provides scoped management of :class:`.Session` objects.
@@ -53,6 +99,10 @@ class scoped_session(object):
else:
self.registry = ThreadLocalRegistry(session_factory)
+ @property
+ def _proxied(self):
+ return self.registry()
+
def __call__(self, **kw):
r"""Return the current :class:`.Session`, creating it
using the :attr:`.scoped_session.session_factory` if not present.
@@ -156,50 +206,3 @@ class scoped_session(object):
ScopedSession = scoped_session
"""Old name for backwards compatibility."""
-
-
-def instrument(name):
- def do(self, *args, **kwargs):
- return getattr(self.registry(), name)(*args, **kwargs)
-
- return do
-
-
-for meth in Session.public_methods:
- setattr(scoped_session, meth, instrument(meth))
-
-
-def makeprop(name):
- def set_(self, attr):
- setattr(self.registry(), name, attr)
-
- def get(self):
- return getattr(self.registry(), name)
-
- return property(get, set_)
-
-
-for prop in (
- "bind",
- "dirty",
- "deleted",
- "new",
- "identity_map",
- "is_active",
- "autoflush",
- "no_autoflush",
- "info",
- "autocommit",
-):
- setattr(scoped_session, prop, makeprop(prop))
-
-
-def clslevel(name):
- def do(cls, *args, **kwargs):
- return getattr(Session, name)(*args, **kwargs)
-
- return classmethod(do)
-
-
-for prop in ("close_all", "object_session", "identity_key"):
- setattr(scoped_session, prop, clslevel(prop))