diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-10-04 11:17:26 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-10-04 11:17:26 -0400 |
commit | f0ea9e37f94bd39fa4f0785dbdcd0ee1759c4a11 (patch) | |
tree | 1010a692ac8a75339970b3adf46c59248c23d454 /lib | |
parent | 728ce8cc480d0ada690e5a97067cff821b9a65f3 (diff) | |
download | sqlalchemy-f0ea9e37f94bd39fa4f0785dbdcd0ee1759c4a11.tar.gz |
Use SQL Server SERVERPROPERTY for version info w/ pyodbc
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-Id: I4ff49ae13c8ff51bd764980131d41c18d73d87ce
Fixes: #3814
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sqlalchemy/connectors/pyodbc.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/base.py | 15 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/pyodbc.py | 21 |
3 files changed, 27 insertions, 13 deletions
diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py index 68bbcc435..1811229d7 100644 --- a/lib/sqlalchemy/connectors/pyodbc.py +++ b/lib/sqlalchemy/connectors/pyodbc.py @@ -153,7 +153,6 @@ class PyODBCConnector(Connector): # run other initialization which asks for user name, etc. super(PyODBCConnector, self).initialize(connection) - def _dbapi_version(self): if not self.dbapi: return () @@ -172,6 +171,9 @@ class PyODBCConnector(Connector): 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('[.\-]') diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 20b812731..9db025df7 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -571,6 +571,8 @@ from ...util import update_wrapper 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,) @@ -1712,18 +1714,9 @@ class MSDialect(default.DefaultDialect): 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__: diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py index 45c091cfb..30db94e49 100644 --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py @@ -104,8 +104,9 @@ versioning. 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): @@ -269,4 +270,22 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect): 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 |