From: Mike Bayer Date: Thu, 4 Nov 2021 17:36:43 +0000 (-0400) Subject: Update "transaction has already begun" language X-Git-Tag: rel_1_4_27~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71feeb37ca8e6726327aa1f24cf7de458dea6f82;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Update "transaction has already begun" language As future connections will now be autobeginning, there will be more cases where begin() can't be called as well as where isolation level can't be set, which will be surprising as this is a behavioral change for 2.0; additionally, when DBAPI autocommit is set, there isn't actually a DBAPI level transaction in effect even though Connection has a Transaction object. Clarify the language in these two error messages to make it clear that begin() and autobegin are tracking a SQLAlchemy-level Transaction() object, whether or not the DBAPI has actually started a transaction, and that this is the reason rollback() or commit() is required before performing the requsted operation. Additionally make sure the error message mentions "autobegin" as a likely reason this error is being encountered along with what Connection needs the user to do in order to resolve. Change-Id: If8763939eeabc46aa9d9209a56d05ad82b892c5c (cherry picked from commit fee0855bfe2982927ab21ce7398fa48b90af7ca4) --- diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 2444b5c7fe..0c27ea6d91 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -764,7 +764,10 @@ class Connection(Connectable): else: if self._is_future: raise exc.InvalidRequestError( - "a transaction is already begun for this connection" + "This connection has already initialized a SQLAlchemy " + "Transaction() object via begin() or autobegin; can't " + "call begin() here unless rollback() or commit() " + "is called first." ) else: return MarkerTransaction(self) diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 75bca19050..1adb886174 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -631,8 +631,10 @@ class DefaultDialect(interfaces.Dialect): if trans_objs: if connection._is_future: raise exc.InvalidRequestError( - "This connection has already begun a transaction; " - "%s may not be altered until transaction end" + "This connection has already initialized a SQLAlchemy " + "Transaction() object via begin() or autobegin; " + "%s may not be altered unless rollback() or commit() " + "is called first." % (", ".join(name for name, obj in trans_objs)) ) else: diff --git a/test/engine/test_transaction.py b/test/engine/test_transaction.py index b8e7edc652..9e61420223 100644 --- a/test/engine/test_transaction.py +++ b/test/engine/test_transaction.py @@ -1568,8 +1568,10 @@ class FutureTransactionTest(fixtures.FutureEngineMixin, fixtures.TablesTest): with testing.db.begin() as conn: assert_raises_message( exc.InvalidRequestError, - "This connection has already begun a transaction; " - "isolation_level may not be altered until transaction end", + r"This connection has already initialized a SQLAlchemy " + r"Transaction\(\) object via begin\(\) or autobegin; " + r"isolation_level may not be altered unless rollback\(\) or " + r"commit\(\) is called first.", conn.execution_options, isolation_level="AUTOCOMMIT", ) @@ -1582,8 +1584,10 @@ class FutureTransactionTest(fixtures.FutureEngineMixin, fixtures.TablesTest): assert_raises_message( exc.InvalidRequestError, - "This connection has already begun a transaction; " - "isolation_level may not be altered until transaction end", + r"This connection has already initialized a SQLAlchemy " + r"Transaction\(\) object via begin\(\) or autobegin; " + r"isolation_level may not be altered unless rollback\(\) or " + r"commit\(\) is called first.", conn.execution_options, isolation_level="AUTOCOMMIT", ) @@ -1822,7 +1826,10 @@ class FutureTransactionTest(fixtures.FutureEngineMixin, fixtures.TablesTest): assert_raises_message( exc.InvalidRequestError, - "a transaction is already begun for this connection", + r"This connection has already initialized a SQLAlchemy " + r"Transaction\(\) object via begin\(\) or autobegin; can't " + r"call begin\(\) here unless rollback\(\) or commit\(\) is " + r"called first.", conn.begin, )