summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/session.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/session.py')
-rw-r--r--lib/sqlalchemy/orm/session.py175
1 files changed, 34 insertions, 141 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index bb12f7021..415826e5f 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -556,7 +556,8 @@ class SessionTransaction(TransactionalContext):
:class:`.SessionTransaction` is at the top of the stack, and
corresponds to a real "COMMIT"/"ROLLBACK"
block. If non-``None``, then this is either a "subtransaction"
- or a "nested" / SAVEPOINT transaction. If the
+ (an internal marker object used by the flush process) or a
+ "nested" / SAVEPOINT transaction. If the
:attr:`.SessionTransaction.nested` attribute is ``True``, then
this is a SAVEPOINT, and if ``False``, indicates this a subtransaction.
@@ -950,29 +951,18 @@ class Session(_SessionClassMethods):
_is_asyncio = False
- @util.deprecated_params(
- autocommit=(
- "2.0",
- "The :paramref:`.Session.autocommit` parameter is deprecated "
- "and will be removed in SQLAlchemy version 2.0. The "
- ':class:`_orm.Session` now features "autobegin" behavior '
- "such that the :meth:`.Session.begin` method may be called "
- "if a transaction has not yet been started yet. See the section "
- ":ref:`session_explicit_begin` for background.",
- ),
- )
def __init__(
self,
bind=None,
autoflush=True,
future=False,
expire_on_commit=True,
- autocommit=False,
twophase=False,
binds=None,
enable_baked_queries=True,
info=None,
query_cls=None,
+ autocommit=False,
):
r"""Construct a new Session.
@@ -980,25 +970,11 @@ class Session(_SessionClassMethods):
generate a :class:`.Session`-producing callable with a given
set of arguments.
- :param autocommit:
- Defaults to ``False``. When ``True``, the
- :class:`.Session` does not automatically begin transactions for
- individual statement executions, will acquire connections from the
- engine on an as-needed basis, releasing to the connection pool
- after each statement. Flushes will begin and commit (or possibly
- rollback) their own transaction if no transaction is present.
- When using this mode, the
- :meth:`.Session.begin` method may be used to explicitly start
- transactions, but the usual "autobegin" behavior is not present.
-
:param autoflush: When ``True``, all query operations will issue a
:meth:`~.Session.flush` call to this ``Session`` before proceeding.
This is a convenience feature so that :meth:`~.Session.flush` need
not be called repeatedly in order for database queries to retrieve
- results. It's typical that ``autoflush`` is used in conjunction
- with ``autocommit=False``. In this scenario, explicit calls to
- :meth:`~.Session.flush` are rarely needed; you usually only need to
- call :meth:`~.Session.commit` (which flushes) to finalize changes.
+ results.
:param bind: An optional :class:`_engine.Engine` or
:class:`_engine.Connection` to
@@ -1077,10 +1053,6 @@ class Session(_SessionClassMethods):
otherwise be configured against the :class:`_orm.sessionmaker`
in use
- * The "subtransactions" feature of :meth:`_orm.Session.begin` is
- removed in version 2.0 and is disabled when the future flag is
- set.
-
* The behavior of the :paramref:`_orm.relationship.cascade_backrefs`
flag on a :func:`_orm.relationship` will always assume
"False" behavior.
@@ -1111,7 +1083,19 @@ class Session(_SessionClassMethods):
called. This allows each database to roll back the entire
transaction, before each transaction is committed.
+ :param autocommit: the "autocommit" keyword is present for backwards
+ compatibility but must remain at its default value of ``False``.
+
"""
+
+ # considering allowing the "autocommit" keyword to still be accepted
+ # as long as it's False, so that external test suites, oslo.db etc
+ # continue to function as the argument appears to be passed in lots
+ # of cases including in our own test suite
+ if autocommit:
+ raise sa_exc.ArgumentError(
+ "autocommit=True is no longer supported"
+ )
self.identity_map = identity.WeakInstanceDict()
self._new = {} # InstanceState->object, strong refs object
@@ -1128,15 +1112,6 @@ class Session(_SessionClassMethods):
self.expire_on_commit = expire_on_commit
self.enable_baked_queries = enable_baked_queries
- if autocommit:
- if future:
- raise sa_exc.ArgumentError(
- "Cannot use autocommit mode with future=True."
- )
- self.autocommit = True
- else:
- self.autocommit = False
-
self.twophase = twophase
self._query_cls = query_cls if query_cls else query.Query
if info:
@@ -1248,7 +1223,7 @@ class Session(_SessionClassMethods):
return {}
def _autobegin(self):
- if not self.autocommit and self._transaction is None:
+ if self._transaction is None:
trans = SessionTransaction(self, autobegin=True)
assert self._transaction is trans
@@ -1256,17 +1231,7 @@ class Session(_SessionClassMethods):
return False
- @util.deprecated_params(
- subtransactions=(
- "2.0",
- "The :paramref:`_orm.Session.begin.subtransactions` flag is "
- "deprecated and "
- "will be removed in SQLAlchemy version 2.0. See "
- "the documentation at :ref:`session_subtransactions` for "
- "background on a compatible alternative pattern.",
- )
- )
- def begin(self, subtransactions=False, nested=False, _subtrans=False):
+ def begin(self, nested=False, _subtrans=False):
"""Begin a transaction, or nested transaction,
on this :class:`.Session`, if one is not already begun.
@@ -1284,13 +1249,10 @@ class Session(_SessionClassMethods):
documentation on SAVEPOINT transactions, please see
:ref:`session_begin_nested`.
- :param subtransactions: if True, indicates that this
- :meth:`~.Session.begin` can create a "subtransaction".
-
:return: the :class:`.SessionTransaction` object. Note that
:class:`.SessionTransaction`
acts as a Python context manager, allowing :meth:`.Session.begin`
- to be used in a "with" block. See :ref:`session_autocommit` for
+ to be used in a "with" block. See :ref:`session_explicit_begin` for
an example.
.. seealso::
@@ -1304,18 +1266,12 @@ class Session(_SessionClassMethods):
"""
- if subtransactions and self.future:
- raise NotImplementedError(
- "subtransactions are not implemented in future "
- "Session objects."
- )
-
if self._autobegin():
- if not subtransactions and not nested and not _subtrans:
+ if not nested and not _subtrans:
return self._transaction
if self._transaction is not None:
- if subtransactions or _subtrans or nested:
+ if _subtrans or nested:
trans = self._transaction._begin(nested=nested)
assert self._transaction is trans
if nested:
@@ -1324,18 +1280,13 @@ class Session(_SessionClassMethods):
raise sa_exc.InvalidRequestError(
"A transaction is already begun on this Session."
)
- elif not self.autocommit:
+ else:
# outermost transaction. must be a not nested and not
# a subtransaction
- assert not nested and not _subtrans and not subtransactions
+ assert not nested and not _subtrans
trans = SessionTransaction(self)
assert self._transaction is trans
- else:
- # legacy autocommit mode
- assert not self.future
- trans = SessionTransaction(self, nested=nested)
- assert self._transaction is trans
return self._transaction # needed for __enter__/__exit__ hook
@@ -1407,13 +1358,6 @@ class Session(_SessionClassMethods):
transaction is committed unconditionally, automatically releasing any
SAVEPOINTs in effect.
- When using legacy "autocommit" mode, this method is only
- valid to call if a transaction is actually in progress, else
- an error is raised. Similarly, when using legacy "subtransactions",
- the method will instead close out the current "subtransaction",
- rather than the actual database transaction, if a transaction
- is in progress.
-
.. seealso::
:ref:`session_committing`
@@ -1444,29 +1388,17 @@ class Session(_SessionClassMethods):
self._transaction.prepare()
- def connection(
- self,
- bind_arguments=None,
- close_with_result=False,
- execution_options=None,
- **kw
- ):
+ def connection(self, bind_arguments=None, execution_options=None, **kw):
r"""Return a :class:`_engine.Connection` object corresponding to this
:class:`.Session` object's transactional state.
- If this :class:`.Session` is configured with ``autocommit=False``,
- either the :class:`_engine.Connection` corresponding to the current
+ Either the :class:`_engine.Connection` corresponding to the current
transaction is returned, or if no transaction is in progress, a new
one is begun and the :class:`_engine.Connection`
returned (note that no
transactional state is established with the DBAPI until the first
SQL statement is emitted).
- Alternatively, if this :class:`.Session` is configured with
- ``autocommit=True``, an ad-hoc :class:`_engine.Connection` is returned
- using :meth:`_engine.Engine.connect` on the underlying
- :class:`_engine.Engine`.
-
Ambiguity in multi-bind or unbound :class:`.Session` objects can be
resolved through any of the optional keyword arguments. This
ultimately makes usage of the :meth:`.get_bind` method for resolution.
@@ -1484,16 +1416,6 @@ class Session(_SessionClassMethods):
:param clause:
deprecated; use bind_arguments
- :param close_with_result: Passed to :meth:`_engine.Engine.connect`,
- indicating the :class:`_engine.Connection` should be considered
- "single use", automatically closing when the first result set is
- closed. This flag only has an effect if this :class:`.Session` is
- configured with ``autocommit=True`` and does not already have a
- transaction in progress.
-
- .. deprecated:: 1.4 this parameter is deprecated and will be removed
- in SQLAlchemy 2.0
-
:param execution_options: a dictionary of execution options that will
be passed to :meth:`_engine.Connection.execution_options`, **when the
connection is first procured only**. If the connection is already
@@ -1518,24 +1440,17 @@ class Session(_SessionClassMethods):
return self._connection_for_bind(
bind,
- close_with_result=close_with_result,
execution_options=execution_options,
)
def _connection_for_bind(self, engine, execution_options=None, **kw):
TransactionalContext._trans_ctx_check(self)
- if self._transaction is not None or self._autobegin():
- return self._transaction._connection_for_bind(
- engine, execution_options
- )
-
- assert self._transaction is None
- assert self.autocommit
- conn = engine.connect(**kw)
- if execution_options:
- conn = conn.execution_options(**execution_options)
- return conn
+ if self._transaction is None:
+ assert self._autobegin()
+ return self._transaction._connection_for_bind(
+ engine, execution_options
+ )
def execute(
self,
@@ -1676,16 +1591,7 @@ class Session(_SessionClassMethods):
bind = self.get_bind(**bind_arguments)
- if self.autocommit:
- # legacy stuff, we can't use future_result w/ autocommit because
- # we rely upon close_with_result, also legacy. it's all
- # interrelated
- conn = self._connection_for_bind(bind, close_with_result=True)
- execution_options = execution_options.union(
- dict(future_result=False)
- )
- else:
- conn = self._connection_for_bind(bind)
+ conn = self._connection_for_bind(bind)
result = conn._execute_20(statement, params or {}, execution_options)
if compile_state_cls:
@@ -2344,8 +2250,8 @@ class Session(_SessionClassMethods):
expire all state whenever the :meth:`Session.rollback`
or :meth:`Session.commit` methods are called, so that new
state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire_all` should not be needed when
- autocommit is ``False``, assuming the transaction is isolated.
+ calling :meth:`Session.expire_all` is not usually needed,
+ assuming the transaction is isolated.
.. seealso::
@@ -3322,10 +3228,6 @@ class Session(_SessionClassMethods):
You may flush() as often as you like within a transaction to move
changes from Python to the database's transaction buffer.
- For ``autocommit`` Sessions with no active manual transaction, flush()
- will create a transaction on the fly that surrounds the entire set of
- operations into the flush.
-
:param objects: Optional; restricts the flush operation to operate
only on elements that are in the given collection.
@@ -3914,12 +3816,7 @@ class Session(_SessionClassMethods):
:meth:`_orm.Session.in_transaction`
"""
- if self.autocommit:
- return (
- self._transaction is not None and self._transaction.is_active
- )
- else:
- return self._transaction is None or self._transaction.is_active
+ return self._transaction is None or self._transaction.is_active
identity_map = None
"""A mapping of object identities to objects themselves.
@@ -4090,7 +3987,6 @@ class sessionmaker(_SessionClassMethods):
bind=None,
class_=Session,
autoflush=True,
- autocommit=False,
expire_on_commit=True,
info=None,
**kw
@@ -4108,8 +4004,6 @@ class sessionmaker(_SessionClassMethods):
objects. Defaults to :class:`.Session`.
:param autoflush: The autoflush setting to use with newly created
:class:`.Session` objects.
- :param autocommit: The autocommit setting to use with newly created
- :class:`.Session` objects.
:param expire_on_commit=True: the
:paramref:`_orm.Session.expire_on_commit` setting to use
with newly created :class:`.Session` objects.
@@ -4125,7 +4019,6 @@ class sessionmaker(_SessionClassMethods):
"""
kw["bind"] = bind
kw["autoflush"] = autoflush
- kw["autocommit"] = autocommit
kw["expire_on_commit"] = expire_on_commit
if info is not None:
kw["info"] = info