From: Mike Bayer Date: Fri, 21 Sep 2012 21:43:22 +0000 (-0400) Subject: finished fixes for mxodbc; need to use at least version 3.2.1 X-Git-Tag: rel_0_8_0b1~148 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7e815c67a9b90774fbb9fa1865a7d79113ef3612;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git finished fixes for mxodbc; need to use at least version 3.2.1 --- diff --git a/CHANGES b/CHANGES index f8991bd038..205e035edf 100644 --- a/CHANGES +++ b/CHANGES @@ -612,6 +612,10 @@ underneath "0.7.xx". needs to be modified to use column.in_(select) explicitly. [ticket:2277] + - [feature] updated support for the mxodbc + driver; mxodbc 3.2.1 is recommended for full + compatibility. + - postgresql - [feature] postgresql.ARRAY features an optional diff --git a/lib/sqlalchemy/connectors/mxodbc.py b/lib/sqlalchemy/connectors/mxodbc.py index 69a8677e42..d74e9639b3 100644 --- a/lib/sqlalchemy/connectors/mxodbc.py +++ b/lib/sqlalchemy/connectors/mxodbc.py @@ -134,23 +134,14 @@ class MxODBCConnector(Connector): if context: native_odbc_execute = context.execution_options.\ get('native_odbc_execute', 'auto') - if native_odbc_execute is True: - # user specified native_odbc_execute=True - return False - elif native_odbc_execute is False: - # user specified native_odbc_execute=False - return True - elif context.is_crud: - # statement is UPDATE, DELETE, INSERT - return False - else: - # all other statements - return True + # default to direct=True in all cases, is more generally + # compatible especially with SQL Server + return False if native_odbc_execute is True else True else: return True - #def do_executemany(self, cursor, statement, parameters, context=None): - # cursor.executemany(statement, parameters, direct=self._get_direct(context)) + def do_executemany(self, cursor, statement, parameters, context=None): + cursor.executemany(statement, parameters, direct=self._get_direct(context)) def do_execute(self, cursor, statement, parameters, context=None): cursor.execute(statement, parameters, direct=self._get_direct(context)) diff --git a/lib/sqlalchemy/dialects/mssql/mxodbc.py b/lib/sqlalchemy/dialects/mssql/mxodbc.py index 0044b5f4fc..4e0af2d396 100644 --- a/lib/sqlalchemy/dialects/mssql/mxodbc.py +++ b/lib/sqlalchemy/dialects/mssql/mxodbc.py @@ -54,12 +54,15 @@ of ``False`` will unconditionally use string-escaped parameters. from ... import types as sqltypes from ...connectors.mxodbc import MxODBCConnector -from .pyodbc import MSExecutionContext_pyodbc +from .pyodbc import MSExecutionContext_pyodbc, _MSNumeric_pyodbc from .base import (MSDialect, MSSQLStrictCompiler, _MSDateTime, _MSDate, _MSTime) +class _MSNumeric_mxodbc(_MSNumeric_pyodbc): + """Include pyodbc's numeric processor. + """ class _MSDate_mxodbc(_MSDate): def bind_processor(self, dialect): @@ -91,12 +94,17 @@ class MSExecutionContext_mxodbc(MSExecutionContext_pyodbc): class MSDialect_mxodbc(MxODBCConnector, MSDialect): - # TODO: may want to use this only if FreeTDS is not in use, - # since FreeTDS doesn't seem to use native binds. - statement_compiler = MSSQLStrictCompiler + # this is only needed if "native ODBC" mode is used, + # which is now disabled by default. + #statement_compiler = MSSQLStrictCompiler + execution_ctx_cls = MSExecutionContext_mxodbc + + # flag used by _MSNumeric_mxodbc + _need_decimal_fix = True + colspecs = { - #sqltypes.Numeric : _MSNumeric, + sqltypes.Numeric : _MSNumeric_mxodbc, sqltypes.DateTime : _MSDateTime, sqltypes.Date : _MSDate_mxodbc, sqltypes.Time : _MSTime_mxodbc, diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py index 83bf7ee6b0..10149689af 100644 --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py @@ -119,9 +119,8 @@ from ...util.compat import decimal class _MSNumeric_pyodbc(sqltypes.Numeric): """Turns Decimals with adjusted() < 0 or > 7 into strings. - This is the only method that is proven to work with Pyodbc+MSSQL - without crashing (floats can be used but seem to cause sporadic - crashes). + The routines here are needed for older pyodbc versions + as well as current mxODBC versions. """ diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index 94b9dfb7b3..6a08cab69c 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -1182,7 +1182,6 @@ class EngineEventsTest(fixtures.TestBase): 'c2': 'some data', 'c1': 5}, (5, 'some data')), ('SELECT lower', {'lower_2': 'Foo'}, - () if testing.against('mssql+mxodbc') else ('Foo', )), ('INSERT INTO t1 (c1, c2)', {'c2': 'foo', 'c1': 6}, @@ -1449,8 +1448,7 @@ class ProxyConnectionTest(fixtures.TestBase): ('INSERT INTO t1 (c1, c2)', {'c2': 'some data', 'c1' : 5}, (5, 'some data')), ('SELECT lower', {'lower_2': 'Foo'}, - () if testing.against('mssql+mxodbc') - else ('Foo', )), + ('Foo', )), ('INSERT INTO t1 (c1, c2)', {'c2': 'foo', 'c1': 6}, (6, 'foo')), ('select * from t1', {}, ()), diff --git a/test/ext/test_horizontal_shard.py b/test/ext/test_horizontal_shard.py index f4f900b95b..93ebae48fa 100644 --- a/test/ext/test_horizontal_shard.py +++ b/test/ext/test_horizontal_shard.py @@ -1,7 +1,7 @@ import datetime, os from sqlalchemy import * from sqlalchemy import event -from sqlalchemy import sql +from sqlalchemy import sql, util from sqlalchemy.orm import * from sqlalchemy.ext.horizontal_shard import ShardedSession from sqlalchemy.sql import operators @@ -13,6 +13,8 @@ from nose import SkipTest # TODO: ShardTest can be turned into a base for further subclasses class ShardTest(fixtures.TestBase): + __skip_if__ = (lambda: util.win32,) + def setUp(self): global db1, db2, db3, db4, weather_locations, weather_reports diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index 0aa5e53410..0c36fe28c4 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -669,6 +669,7 @@ class MetaDataTest(fixtures.TestBase, ComparesTables): ) class TableTest(fixtures.TestBase, AssertsCompiledSQL): + @testing.skip_if('mssql', 'different col format') def test_prefixes(self): from sqlalchemy import Table table1 = Table("temporary_table_1", MetaData(), diff --git a/test/sql/test_query.py b/test/sql/test_query.py index a0c849de53..642da8dece 100644 --- a/test/sql/test_query.py +++ b/test/sql/test_query.py @@ -1179,7 +1179,6 @@ class QueryTest(fixtures.TestBase): @testing.emits_warning('.*empty sequence.*') @testing.fails_on('firebird', "uses sql-92 rules") @testing.fails_on('sybase', "uses sql-92 rules") - @testing.fails_on('mssql+mxodbc', "uses sql-92 rules") @testing.fails_if(lambda: testing.against('mssql+pyodbc') and not testing.db.dialect.freetds, "uses sql-92 rules") diff --git a/test/sql/test_update.py b/test/sql/test_update.py index 0c629f9aa9..79079e5127 100644 --- a/test/sql/test_update.py +++ b/test/sql/test_update.py @@ -133,7 +133,6 @@ class UpdateFromCompileTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCom ) class UpdateFromRoundTripTest(_UpdateFromTestBase, fixtures.TablesTest): - __testing_engine__ = {'execution_options':{'native_odbc_execute':False}} @testing.requires.update_from def test_exec_two_table(self):