diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-07-29 14:06:43 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-07-29 14:06:43 -0400 |
| commit | 83326bf44c590a3b22ddf9bf658f509d1491bc0f (patch) | |
| tree | 2f67a8167450d44753eb9cc2b2b3044decd3354d /test | |
| parent | 405c223ae50e78dacac08783c414619db20df0b7 (diff) | |
| download | sqlalchemy-83326bf44c590a3b22ddf9bf658f509d1491bc0f.tar.gz | |
- The exception wrapping system for DBAPI errors can now accommodate
non-standard DBAPI exceptions, such as the psycopg2
TransactionRollbackError. These exceptions will now be raised
using the closest available subclass in ``sqlalchemy.exc``, in the
case of TransactionRollbackError, ``sqlalchemy.exc.OperationalError``.
fixes #3075
Diffstat (limited to 'test')
| -rw-r--r-- | test/dialect/postgresql/test_dialect.py | 10 | ||||
| -rw-r--r-- | test/engine/test_execute.py | 27 |
2 files changed, 36 insertions, 1 deletions
diff --git a/test/dialect/postgresql/test_dialect.py b/test/dialect/postgresql/test_dialect.py index 11b277b66..b751bbcdd 100644 --- a/test/dialect/postgresql/test_dialect.py +++ b/test/dialect/postgresql/test_dialect.py @@ -65,6 +65,16 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL): assert testing.db.dialect.dbapi.__version__.\ startswith(".".join(str(x) for x in v)) + @testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature') + def test_psycopg2_non_standard_err(self): + from psycopg2.extensions import TransactionRollbackError + import psycopg2 + + exception = exc.DBAPIError.instance( + "some statement", {}, TransactionRollbackError("foo"), + psycopg2.Error) + assert isinstance(exception, exc.OperationalError) + # currently not passing with pg 9.3 that does not seem to generate # any notices here, would rather find a way to mock this @testing.requires.no_coverage diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index efce371a5..36f3fbf72 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -20,7 +20,7 @@ from sqlalchemy.engine import result as _result, default from sqlalchemy.engine.base import Engine from sqlalchemy.testing import fixtures from sqlalchemy.testing.mock import Mock, call, patch -from contextlib import contextmanager +from contextlib import contextmanager, nested users, metadata, users_autoinc = None, None, None class ExecuteTest(fixtures.TestBase): @@ -236,6 +236,31 @@ class ExecuteTest(fixtures.TestBase): ) eq_(is_disconnect.call_count, 0) + def test_exception_wrapping_non_standard_dbapi_error(self): + class DBAPIError(Exception): + pass + + class OperationalError(DBAPIError): + pass + + class NonStandardException(OperationalError): + pass + + with nested( + patch.object(testing.db.dialect, "dbapi", Mock(Error=DBAPIError)), + patch.object( + testing.db.dialect, "is_disconnect", + lambda *arg: False), + patch.object( + testing.db.dialect, "do_execute", + Mock(side_effect=NonStandardException)), + ): + with testing.db.connect() as conn: + assert_raises( + tsa.exc.OperationalError, + conn.execute, "select 1" + ) + def test_exception_wrapping_non_dbapi_statement(self): class MyType(TypeDecorator): |
