SQL server / pyodbc allows non-int tokens in version tuple which fails on comparison

Issue #4227 resolved
Michael Bayer
repo owner created an issue

e.g. stack trace like:

    return once_fn(*arg, **kw)
  File "C:\Users\m.m\Envs\mentrix\lib\site-packages\sqlalchemy\engine\strategies.py", line 183, in first_connect
    dialect.initialize(c)
  File "C:\Users\m.m\Envs\mentrix\lib\site-packages\sqlalchemy\dialects\mssql\base.py", line 1931, in initialize
    super(MSDialect, self).initialize(connection)
  File "C:\Users\m.m\Envs\mentrix\lib\site-packages\sqlalchemy\engine\default.py", line 267, in initialize
    self._get_default_schema_name(connection)
  File "C:\Users\m.m\Envs\mentrix\lib\site-packages\sqlalchemy\dialects\mssql\base.py", line 1958, in _get_default_schema_name
    if self.server_version_info < MS_2005_VERSION:
TypeError: '<' not supported between instances of 'str' and 'int'

we should not be allowing non-int tokens in the version string at all:

diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py
index 14e8ae838..30b8b8b50 100644
--- a/lib/sqlalchemy/dialects/mssql/pyodbc.py
+++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py
@@ -291,7 +291,7 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect):
                 try:
                     version.append(int(n))
                 except ValueError:
-                    version.append(n)
+                    pass
             return tuple(version)

     def is_disconnect(self, e, connection, cursor):

however, need to figure out what version string this user is getting as we still need to locate the numeric tokens.

Comments (4)

  1. Michael Bayer reporter

    we need to repair and test individually for the pyodbc fallback as well using a mock:

    diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py
    index d8c3fcec4..ae2b740b0 100644
    --- a/lib/sqlalchemy/connectors/pyodbc.py
    +++ b/lib/sqlalchemy/connectors/pyodbc.py
    @@ -145,7 +145,7 @@ class PyODBCConnector(Connector):
                 try:
                     version.append(int(n))
                 except ValueError:
    -                version.append(n)
    +                pass
             return tuple(version)
    
         def set_isolation_level(self, connection, level):
    diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py
    index 14e8ae838..30b8b8b50 100644
    --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py
    +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py
    @@ -291,7 +291,7 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect):
                     try:
                         version.append(int(n))
                     except ValueError:
    -                    version.append(n)
    +                    pass
                 return tuple(version)
    
         def is_disconnect(self, e, connection, cursor):
    
  2. Michael Bayer reporter

    so the user was using a non-SQL Server database so in that sense this bug is invalid, however we don't want to have non-integer tokens in this value in any case so the change is still useful.

  3. Michael Bayer reporter

    Filter non-integer characters from pyodbc SQL Server version

    Adjusted the SQL Server version detection for pyodbc to only allow for numeric tokens, filtering out non-integers, since the dialect does tuple- numeric comparisons with this value. This is normally true for all known SQL Server / pyodbc drivers in any case.

    Change-Id: I4ab18a07e19231091b5e877ba1fccd5eda72a992 Fixes: #4227

    → <<cset f55c4f6bd2cb>>

  4. Michael Bayer reporter

    Filter non-integer characters from pyodbc SQL Server version

    Adjusted the SQL Server version detection for pyodbc to only allow for numeric tokens, filtering out non-integers, since the dialect does tuple- numeric comparisons with this value. This is normally true for all known SQL Server / pyodbc drivers in any case.

    Change-Id: I4ab18a07e19231091b5e877ba1fccd5eda72a992 Fixes: #4227 (cherry picked from commit f55c4f6bd2cb2f2b18e62159361ce7ecb5897396)

    → <<cset 6ddf0b020051>>

  5. Log in to comment