From: Mike Bayer Date: Thu, 18 Mar 2010 16:05:20 +0000 (-0400) Subject: turning the decimals to floats allows the E notation to work with sybase+pyodbc for... X-Git-Tag: rel_0_6beta2~37^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77fa087d1577dedbb18c197641bf81e6d0862505;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git turning the decimals to floats allows the E notation to work with sybase+pyodbc for small E notations --- diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 070650d97f..6425291c8a 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -283,7 +283,8 @@ class _MSNumeric(sqltypes.Numeric): # TODO: this seems exceedingly complex. # need to know exactly what tests cover this, so far # test_types.NumericTest.test_enotation_decimal - + # see the _SybNumeric type in sybase/pyodbc for possible + # generalized solution on pyodbc if isinstance(value, decimal.Decimal): if value.adjusted() < 0: result = "%s0.%s%s" % ( diff --git a/lib/sqlalchemy/dialects/sybase/base.py b/lib/sqlalchemy/dialects/sybase/base.py index e182cc9e7c..5814f70da3 100644 --- a/lib/sqlalchemy/dialects/sybase/base.py +++ b/lib/sqlalchemy/dialects/sybase/base.py @@ -85,6 +85,7 @@ RESERVED_WORDS = set([ "within", "work", "writetext", ]) + class _SybaseUnitypeMixin(object): """these types appear to return a buffer object.""" @@ -161,9 +162,6 @@ class SybaseTypeCompiler(compiler.GenericTypeCompiler): def visit_UNIQUEIDENTIFIER(self, type_): return "UNIQUEIDENTIFIER" -colspecs = { -} - ischema_names = { 'integer' : INTEGER, 'unsigned int' : INTEGER, # TODO: unsigned flags @@ -359,7 +357,7 @@ class SybaseDialect(default.DefaultDialect): supports_unicode_binds = False postfetch_lastrowid = True - colspecs = colspecs + colspecs = {} ischema_names = ischema_names type_compiler = SybaseTypeCompiler diff --git a/lib/sqlalchemy/dialects/sybase/pyodbc.py b/lib/sqlalchemy/dialects/sybase/pyodbc.py index 1bb09251cc..61cf333da9 100644 --- a/lib/sqlalchemy/dialects/sybase/pyodbc.py +++ b/lib/sqlalchemy/dialects/sybase/pyodbc.py @@ -31,6 +31,26 @@ Currently *not* supported are:: from sqlalchemy.dialects.sybase.base import SybaseDialect, SybaseExecutionContext from sqlalchemy.connectors.pyodbc import PyODBCConnector +import decimal +from sqlalchemy import processors, types as sqltypes + +# TODO: should this be part of pyodbc connectors ??? applies to MSSQL too ? +class _SybNumeric(sqltypes.Numeric): + def bind_processor(self, dialect): + super_process = super(_SybNumeric, self).bind_processor(dialect) + + def process(value): + if self.asdecimal and \ + isinstance(value, decimal.Decimal) and \ + value.adjusted() < -6: + return processors.to_float(value) + elif super_process: + return super_process(value) + else: + return value + return process + + class SybaseExecutionContext_pyodbc(SybaseExecutionContext): def set_ddl_autocommit(self, connection, value): if value: @@ -39,7 +59,13 @@ class SybaseExecutionContext_pyodbc(SybaseExecutionContext): connection.autocommit = False + class SybaseDialect_pyodbc(PyODBCConnector, SybaseDialect): execution_ctx_cls = SybaseExecutionContext_pyodbc + colspecs = { + sqltypes.Numeric:_SybNumeric, + sqltypes.Float:sqltypes.Float, + } + dialect = SybaseDialect_pyodbc diff --git a/test/sql/test_types.py b/test/sql/test_types.py index 507ca5a091..56eca39ac5 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -1155,7 +1155,6 @@ class NumericTest(TestBase, AssertsExecutionResults): finally: t.drop(testing.db) - @testing.fails_on('sybase', "Driver doesn't appear to handle E notation, won't accept strings") def test_enotation_decimal(self): """test exceedingly small decimals.