summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-09-28 09:39:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-09-28 09:39:54 -0400
commit6a38697261e271b3600d8f1bbc56f663e5ee9890 (patch)
tree763bbb37be51f74bb4d09c2940f54aa30bcbb4d5
parentdc4d1ee7bdf8f9670057e916a29f1f5252e77207 (diff)
downloadsqlalchemy-6a38697261e271b3600d8f1bbc56f663e5ee9890.tar.gz
Add full list of pyodbc error codes for MSSQL
Moved the SQL server error codes out of connnectors/pyodbc.py and into mssql/pyodbc.py. Added complete list of odbc-related disconnect codes. Change-Id: Icd84a920dbfa1f188847f859654ff6f7a48170f1 Fixes: #4095
-rw-r--r--doc/build/changelog/unreleased_11/4095.rst9
-rw-r--r--lib/sqlalchemy/connectors/pyodbc.py2
-rw-r--r--lib/sqlalchemy/dialects/mssql/pyodbc.py10
-rw-r--r--test/dialect/mssql/test_engine.py29
4 files changed, 48 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_11/4095.rst b/doc/build/changelog/unreleased_11/4095.rst
new file mode 100644
index 000000000..17286fa25
--- /dev/null
+++ b/doc/build/changelog/unreleased_11/4095.rst
@@ -0,0 +1,9 @@
+.. change::
+ :tags: bug, mssql
+ :tickets: 4095
+ :versions: 1.2.0b3
+
+ Added a full range of "connection closed" exception codes to the
+ PyODBC dialect for SQL Server, including '08S01', '01002', '08003',
+ '08007', '08S02', '08001', 'HYT00', 'HY010'. Previously, only '08S01'
+ was covered. \ No newline at end of file
diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py
index b95b2964f..3e1d1a330 100644
--- a/lib/sqlalchemy/connectors/pyodbc.py
+++ b/lib/sqlalchemy/connectors/pyodbc.py
@@ -111,8 +111,6 @@ class PyODBCConnector(Connector):
if isinstance(e, self.dbapi.ProgrammingError):
return "The cursor's connection has been closed." in str(e) or \
'Attempt to use a closed connection.' in str(e)
- elif isinstance(e, self.dbapi.Error):
- return '[08S01]' in str(e)
else:
return False
diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py
index a667b671e..6fd4fc554 100644
--- a/lib/sqlalchemy/dialects/mssql/pyodbc.py
+++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py
@@ -275,4 +275,14 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect):
version.append(n)
return tuple(version)
+ def is_disconnect(self, e, connection, cursor):
+ if isinstance(e, self.dbapi.Error):
+ for code in (
+ '08S01', '01002', '08003', '08007',
+ '08S02', '08001', 'HYT00', 'HY010'):
+ if code in str(e):
+ return True
+ return super(MSDialect_pyodbc, self).is_disconnect(
+ e, connection, cursor)
+
dialect = MSDialect_pyodbc
diff --git a/test/dialect/mssql/test_engine.py b/test/dialect/mssql/test_engine.py
index 1021f4e99..b69e62572 100644
--- a/test/dialect/mssql/test_engine.py
+++ b/test/dialect/mssql/test_engine.py
@@ -202,6 +202,35 @@ class ParseConnectTest(fixtures.TestBase):
eq_(dialect.is_disconnect("not an error", None, None), False)
+ def test_pyodbc_disconnect(self):
+ dialect = pyodbc.dialect()
+
+ class MockDBAPIError(Exception):
+ pass
+
+ class MockProgrammingError(MockDBAPIError):
+ pass
+
+ dialect.dbapi = Mock(
+ Error=MockDBAPIError, ProgrammingError=MockProgrammingError)
+
+ for error in [
+ MockDBAPIError("[%s] some pyodbc message" % code)
+ for code in [
+ '08S01', '01002', '08003', '08007',
+ '08S02', '08001', 'HYT00', 'HY010']
+ ] + [
+ MockProgrammingError(message)
+ for message in [
+ "(some pyodbc stuff) The cursor's connection has been closed.",
+ "(some pyodbc stuff) Attempt to use a closed connection."
+ ]
+ ]:
+ eq_(dialect.is_disconnect(error, None, None), True)
+
+ eq_(dialect.is_disconnect(
+ MockProgrammingError("not an error"), None, None), False)
+
@testing.requires.mssql_freetds
def test_bad_freetds_warning(self):
engine = engines.testing_engine()