Fixed yet another regression in SQL Server isolation level fetch (see
:ticket:`8231`, :ticket:`8475`), this time with "Microsoft Dynamics CRM
Database via Azure Active Directory", which apparently lacks the
``system_views`` view entirely. Error catching has been extended that under
no circumstances will this method ever fail, provided database connectivity
is present.
Fixes: #8525
Change-Id: I76a429e3329926069a0367d2e77ca1124b9a059d
(cherry picked from commit
0ee7d693b805c0f1aea0da5ebc11ea6e52b42c71)
--- /dev/null
+.. change::
+ :tags: bug, mssql, regression
+ :tickets: 8525
+
+ Fixed yet another regression in SQL Server isolation level fetch (see
+ :ticket:`8231`, :ticket:`8475`), this time with "Microsoft Dynamics CRM
+ Database via Azure Active Directory", which apparently lacks the
+ ``system_views`` view entirely. Error catching has been extended that under
+ no circumstances will this method ever fail, provided database connectivity
+ is present.
\ No newline at end of file
def get_isolation_level(self, dbapi_connection):
cursor = dbapi_connection.cursor()
+ view_name = "sys.system_views"
try:
cursor.execute(
- "SELECT name FROM sys.system_views WHERE name IN "
- "('dm_exec_sessions', 'dm_pdw_nodes_exec_sessions')"
+ (
+ "SELECT name FROM {} WHERE name IN "
+ "('dm_exec_sessions', 'dm_pdw_nodes_exec_sessions')"
+ ).format(view_name)
)
row = cursor.fetchone()
if not row:
view_name = "sys.{}".format(row[0])
- try:
- cursor.execute(
- """
- SELECT CASE transaction_isolation_level
- WHEN 0 THEN NULL
- WHEN 1 THEN 'READ UNCOMMITTED'
- WHEN 2 THEN 'READ COMMITTED'
- WHEN 3 THEN 'REPEATABLE READ'
- WHEN 4 THEN 'SERIALIZABLE'
- WHEN 5 THEN 'SNAPSHOT' END
- AS TRANSACTION_ISOLATION_LEVEL
- FROM {}
- where session_id = @@SPID
- """.format(
- view_name
- )
- )
- except self.dbapi.Error as err:
- util.raise_(
- NotImplementedError(
- "Can't fetch isolation level; encountered "
- "error {} when "
- 'attempting to query the "{}" view.'.format(
- err, view_name
- )
- ),
- from_=err,
+ cursor.execute(
+ """
+ SELECT CASE transaction_isolation_level
+ WHEN 0 THEN NULL
+ WHEN 1 THEN 'READ UNCOMMITTED'
+ WHEN 2 THEN 'READ COMMITTED'
+ WHEN 3 THEN 'REPEATABLE READ'
+ WHEN 4 THEN 'SERIALIZABLE'
+ WHEN 5 THEN 'SNAPSHOT' END
+ AS TRANSACTION_ISOLATION_LEVEL
+ FROM {}
+ where session_id = @@SPID
+ """.format(
+ view_name
)
- else:
- row = cursor.fetchone()
- return row[0].upper()
+ )
+ except self.dbapi.Error as err:
+ util.raise_(
+ NotImplementedError(
+ "Can't fetch isolation level; encountered error {} when "
+ 'attempting to query the "{}" view.'.format(err, view_name)
+ ),
+ from_=err,
+ )
+ else:
+ row = cursor.fetchone()
+ return row[0].upper()
finally:
cursor.close()
class IsolationLevelDetectTest(fixtures.TestBase):
- def _fixture(self, view_result, simulate_perm_failure=False):
+ def _fixture(
+ self,
+ view_result,
+ simulate_perm_failure=False,
+ simulate_no_system_views=False,
+ ):
class Error(Exception):
pass
):
result[:] = []
if "SELECT name FROM sys.system_views" in stmt:
- if view_result:
- result.append((view_result,))
+ if simulate_no_system_views:
+ raise dialect.dbapi.Error(
+ "SQL Server simulated no system_views error"
+ )
+ else:
+ if view_result:
+ result.append((view_result,))
elif re.match(
".*SELECT CASE transaction_isolation_level.*FROM sys.%s"
% (view_result,),
connection,
)
+ @testing.combinations(True, False)
+ def test_no_system_views(self, simulate_perm_failure_also):
+ dialect, connection = self._fixture(
+ "dm_pdw_nodes_exec_sessions",
+ simulate_perm_failure=simulate_perm_failure_also,
+ simulate_no_system_views=True,
+ )
+
+ assert_raises_message(
+ NotImplementedError,
+ r"Can\'t fetch isolation level; encountered error SQL Server "
+ r"simulated no system_views error when attempting to query the "
+ r'"sys.system_views" view.',
+ dialect.get_isolation_level,
+ connection,
+ )
+
def test_dont_have_table_perms(self):
dialect, connection = self._fixture(
"dm_pdw_nodes_exec_sessions", simulate_perm_failure=True