diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-12-08 15:15:02 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-12-08 15:15:02 -0500 |
commit | 06738f665ea936246a3813ad7de01e98ff8d519a (patch) | |
tree | 9f5a09e0d723f477d436636aa31212ecc1a99d8f | |
parent | b7cf11b163dd7d15f56634a41dcceb880821ecf3 (diff) | |
download | sqlalchemy-06738f665ea936246a3813ad7de01e98ff8d519a.tar.gz |
- identify another spot where _handle_dbapi_error() needs to do something
differently for the case where it is called in an already-invalidated state;
don't call upon self.connection
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 7 | ||||
-rw-r--r-- | test/engine/test_parseconnect.py | 28 |
2 files changed, 32 insertions, 3 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index dd8ea275c..9a8610344 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1243,9 +1243,10 @@ class Connection(Connectable): del self._reentrant_error if self._is_disconnect: del self._is_disconnect - dbapi_conn_wrapper = self.connection - self.engine.pool._invalidate(dbapi_conn_wrapper, e) - self.invalidate(e) + if not self.invalidated: + dbapi_conn_wrapper = self.__connection + self.engine.pool._invalidate(dbapi_conn_wrapper, e) + self.invalidate(e) if self.should_close_with_result: self.close() diff --git a/test/engine/test_parseconnect.py b/test/engine/test_parseconnect.py index 4a3da7d1c..8d659420d 100644 --- a/test/engine/test_parseconnect.py +++ b/test/engine/test_parseconnect.py @@ -397,6 +397,34 @@ class CreateEngineTest(fixtures.TestBase): assert not de.connection_invalidated @testing.requires.sqlite + def test_cant_connect_stay_invalidated(self): + e = create_engine('sqlite://') + sqlite3 = e.dialect.dbapi + + class MySpecialException(Exception): + pass + + eng = create_engine('sqlite://') + + @event.listens_for(eng, "handle_error") + def handle_error(ctx): + assert ctx.is_disconnect + + conn = eng.connect() + + conn.invalidate() + + eng.pool._creator = Mock( + side_effect=sqlite3.ProgrammingError( + "Cannot operate on a closed database.")) + + try: + conn.connection + assert False + except tsa.exc.DBAPIError: + assert conn.invalidated + + @testing.requires.sqlite def test_dont_touch_non_dbapi_exception_on_connect(self): e = create_engine('sqlite://') sqlite3 = e.dialect.dbapi |