.. changelog::
:version: 1.0.16
+ .. change::
+ :tags: bug, mssql
+ :tickets: 3814
+ :versions: 1.1.0
+
+ Updated the server version info scheme for pyodbc to use SQL Server
+ SERVERPROPERTY(), rather than relying upon pyodbc.SQL_DBMS_VER, which
+ continues to be unreliable particularly with FreeTDS.
+
.. change::
:tags: bug, orm
:tickets: 3800
# run other initialization which asks for user name, etc.
super(PyODBCConnector, self).initialize(connection)
-
def _dbapi_version(self):
if not self.dbapi:
return ()
return vers
def _get_server_version_info(self, connection):
+ # NOTE: this function is not reliable, particularly when
+ # freetds is in use. Implement database-specific server version
+ # queries.
dbapi_con = connection.connection
version = []
r = re.compile('[.\-]')
from . import information_schema as ischema
# http://sqlserverbuilds.blogspot.com/
+MS_2016_VERSION = (13,)
+MS_2014_VERSION = (12,)
MS_2012_VERSION = (11,)
MS_2008_VERSION = (10,)
MS_2005_VERSION = (9,)
def _setup_version_attributes(self):
if self.server_version_info[0] not in list(range(8, 17)):
- # FreeTDS with version 4.2 seems to report here
- # a number like "95.10.255". Don't know what
- # that is. So emit warning.
- # Use TDS Version 7.0 through 7.3, per the MS information here:
- # https://msdn.microsoft.com/en-us/library/dd339982.aspx
- # and FreeTDS information here (7.3 highest supported version):
- # http://www.freetds.org/userguide/choosingtdsprotocol.htm
util.warn(
- "Unrecognized server version info '%s'. Version specific "
- "behaviors may not function properly. If using ODBC "
- "with FreeTDS, ensure TDS_VERSION 7.0 through 7.3, not "
- "4.2, is configured in the FreeTDS configuration." %
+ "Unrecognized server version info '%s'. Some SQL Server "
+ "features may not function properly." %
".".join(str(x) for x in self.server_version_info))
if self.server_version_info >= MS_2005_VERSION and \
'implicit_returning' not in self.__dict__:
from .base import MSExecutionContext, MSDialect, VARBINARY
from ...connectors.pyodbc import PyODBCConnector
-from ... import types as sqltypes, util
+from ... import types as sqltypes, util, exc
import decimal
+import re
class _ms_numeric_pyodbc(object):
self._need_decimal_fix = self.dbapi and \
self._dbapi_version() < (2, 1, 8)
+ def _get_server_version_info(self, connection):
+ try:
+ raw = connection.scalar("SELECT SERVERPROPERTY('ProductVersion')")
+ except exc.ProgrammingError:
+ # SQL Server docs indicate this function isn't present prior to
+ # 2008
+ return super(MSDialect_pyodbc, self).\
+ _get_server_version_info(connection)
+ else:
+ version = []
+ r = re.compile('[.\-]')
+ for n in r.split(raw):
+ try:
+ version.append(int(n))
+ except ValueError:
+ version.append(n)
+ return tuple(version)
+
dialect = MSDialect_pyodbc