From: Mike Bayer Date: Mon, 5 Aug 2019 17:43:06 +0000 (-0400) Subject: Remove threadlocal strategy docs, remaining contextual_connect X-Git-Tag: rel_1_4_0b1~773 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d45bd29918e217662ea2c0ee44608b0bbf0d4a06;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Remove threadlocal strategy docs, remaining contextual_connect in dfb20f07d8, we merged the removal of the threadlocal strategy from the 1.4 branch. We forgot to take the docs out :). Also, there seems to be an uncovered _contextual_connect call in horizontal shard. Cover that and repair. Fixes: #4632 Closes: #4795 Change-Id: Id05cbbebe34a8f547c9c84369a929a2926c7d093 --- diff --git a/doc/build/core/connections.rst b/doc/build/core/connections.rst index de1bb09100..af745ba604 100644 --- a/doc/build/core/connections.rst +++ b/doc/build/core/connections.rst @@ -499,89 +499,6 @@ use of new connections, and means that when a connection is checked in, it is entirely closed out and is not held in memory. See :ref:`pool_switching` for guidelines on how to disable pooling. -.. _threadlocal_strategy: - -Using the Threadlocal Execution Strategy -======================================== - -The "threadlocal" engine strategy is an optional feature which -can be used by non-ORM applications to associate transactions -with the current thread, such that all parts of the -application can participate in that transaction implicitly without the need to -explicitly reference a :class:`.Connection`. - -.. deprecated:: 1.3 - - The "threadlocal" engine strategy is deprecated, and will be removed - in a future release. - - This strategy is designed for a particular pattern of usage which is - generally considered as a legacy pattern. It has **no impact** on the - "thread safety" of SQLAlchemy components or one's application. It also - should not be used when using an ORM - :class:`~sqlalchemy.orm.session.Session` object, as the - :class:`~sqlalchemy.orm.session.Session` itself represents an ongoing - transaction and itself handles the job of maintaining connection and - transactional resources. - - .. seealso:: - - :ref:`change_4393_threadlocal` - -Enabling ``threadlocal`` is achieved as follows:: - - db = create_engine('mysql://localhost/test', strategy='threadlocal') - -The above :class:`.Engine` will now acquire a :class:`.Connection` using -connection resources derived from a thread-local variable whenever -:meth:`.Engine.execute` or :meth:`.Engine.contextual_connect` is called. This -connection resource is maintained as long as it is referenced, which allows -multiple points of an application to share a transaction while using -connectionless execution:: - - def call_operation1(): - engine.execute("insert into users values (?, ?)", 1, "john") - - def call_operation2(): - users.update(users.c.user_id==5).execute(name='ed') - - db.begin() - try: - call_operation1() - call_operation2() - db.commit() - except: - db.rollback() - -Explicit execution can be mixed with connectionless execution by -using the :meth:`.Engine.connect` method to acquire a :class:`.Connection` -that is not part of the threadlocal scope:: - - db.begin() - conn = db.connect() - try: - conn.execute(log_table.insert(), message="Operation started") - call_operation1() - call_operation2() - db.commit() - conn.execute(log_table.insert(), message="Operation succeeded") - except: - db.rollback() - conn.execute(log_table.insert(), message="Operation failed") - finally: - conn.close() - -To access the :class:`.Connection` that is bound to the threadlocal scope, -call :meth:`.Engine.contextual_connect`:: - - conn = db.contextual_connect() - call_operation3(conn) - conn.close() - -Calling :meth:`~.Connection.close` on the "contextual" connection does not :term:`release` -its resources until all other usages of that resource are closed as well, including -that any ongoing transactions are rolled back or committed. - .. _dbapi_connections: Working with Raw DBAPI Connections diff --git a/doc/build/orm/session_transaction.rst b/doc/build/orm/session_transaction.rst index a9e4591bcf..836861b0ae 100644 --- a/doc/build/orm/session_transaction.rst +++ b/doc/build/orm/session_transaction.rst @@ -23,7 +23,7 @@ with an ongoing transactional state maintained by the :class:`.Session`. When the first :class:`.Engine` is operated upon, the :class:`.Session` can be said to have left the "begin" state and entered "transactional" state. For each :class:`.Engine` encountered, a :class:`.Connection` is associated with it, -which is acquired via the :meth:`.Engine.contextual_connect` method. If a +which is acquired via the :meth:`.Engine.connect` method. If a :class:`.Connection` was directly associated with the :class:`.Session` (see :ref:`session_external_transaction` for an example of this), it is added to the transactional state directly. diff --git a/lib/sqlalchemy/ext/horizontal_shard.py b/lib/sqlalchemy/ext/horizontal_shard.py index c263b17346..f563816856 100644 --- a/lib/sqlalchemy/ext/horizontal_shard.py +++ b/lib/sqlalchemy/ext/horizontal_shard.py @@ -242,7 +242,7 @@ class ShardedSession(Session): else: return self.get_bind( mapper, shard_id=shard_id, instance=instance - )._contextual_connect(**kwargs) + ).connect(**kwargs) def get_bind( self, mapper, shard_id=None, instance=None, clause=None, **kw diff --git a/test/ext/test_horizontal_shard.py b/test/ext/test_horizontal_shard.py index affd7112c6..838590f5b7 100644 --- a/test/ext/test_horizontal_shard.py +++ b/test/ext/test_horizontal_shard.py @@ -517,13 +517,14 @@ class RefreshDeferExpireTest(fixtures.DeclarativeMappedTest): s.add(A(data="d1", deferred_data="d2")) s.commit() - def _session_fixture(self): + def _session_fixture(self, **kw): return ShardedSession( shards={"main": testing.db}, shard_chooser=lambda *args: "main", id_chooser=lambda *args: ["fake", "main"], query_chooser=lambda *args: ["fake", "main"], + **kw ) def test_refresh(self): @@ -548,6 +549,13 @@ class RefreshDeferExpireTest(fixtures.DeclarativeMappedTest): session.expire(a1) eq_(a1.data, "d1") + def test_autocommit_session(self): + A = self.classes.A + session = self._session_fixture(autocommit=True) + a1 = session.query(A).set_shard("main").first() + + eq_(a1.data, "d1") + class LazyLoadIdentityKeyTest(fixtures.DeclarativeMappedTest): def _init_dbs(self):