From: Mike Bayer Date: Fri, 19 Mar 2010 16:30:22 +0000 (-0400) Subject: - get firebird on board X-Git-Tag: rel_0_6beta2~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7de2b6923f214674cf139b21125f41c2752094eb;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - get firebird on board - a lot of these drivers suck at decimals, not sure what to do --- diff --git a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py index 66d001e0c8..9984d32a28 100644 --- a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py +++ b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py @@ -28,13 +28,32 @@ __ http://kinterbasdb.sourceforge.net/dist_docs/usage.html#special_issue_concurr """ from sqlalchemy.dialects.firebird.base import FBDialect, FBCompiler - - +from sqlalchemy import util, types as sqltypes + +class _FBNumeric_kinterbasdb(sqltypes.Numeric): + def bind_processor(self, dialect): + def process(value): + if value is not None: + return str(value) + else: + return value + return process + class FBDialect_kinterbasdb(FBDialect): driver = 'kinterbasdb' supports_sane_rowcount = False supports_sane_multi_rowcount = False - + + supports_native_decimal = True + + colspecs = util.update_copy( + FBDialect.colspecs, + { + sqltypes.Numeric:_FBNumeric_kinterbasdb + } + + ) + def __init__(self, type_conv=200, concurrency_level=1, **kwargs): super(FBDialect_kinterbasdb, self).__init__(**kwargs) diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index eee2bb1bab..c6e9cea5dc 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -82,6 +82,12 @@ from sqlalchemy import types as sqltypes, util, exc from datetime import datetime import random +class _OracleNumeric(sqltypes.Numeric): + # cx_oracle accepts Decimal objects, but returns + # floats + def bind_processor(self, dialect): + return None + class _OracleDate(sqltypes.Date): def bind_processor(self, dialect): return None @@ -188,25 +194,6 @@ class _OracleInterval(oracle.INTERVAL): class _OracleRaw(oracle.RAW): pass -colspecs = { - sqltypes.Date : _OracleDate, # generic type, assume datetime.date is desired - oracle.DATE: oracle.DATE, # non generic type - passthru - sqltypes.LargeBinary : _OracleBinary, - sqltypes.Boolean : oracle._OracleBoolean, - sqltypes.Interval : _OracleInterval, - oracle.INTERVAL : _OracleInterval, - sqltypes.Text : _OracleText, - sqltypes.String : _OracleString, - sqltypes.UnicodeText : _OracleUnicodeText, - sqltypes.CHAR : _OracleChar, - sqltypes.Integer : _OracleInteger, # this is only needed for OUT parameters. - # it would be nice if we could not use it otherwise. - oracle.NUMBER : oracle.NUMBER, # don't let this get converted - oracle.RAW: _OracleRaw, - sqltypes.Unicode: _OracleNVarChar, - sqltypes.NVARCHAR : _OracleNVarChar, -} - class OracleCompiler_cx_oracle(OracleCompiler): def bindparam_string(self, name): if self.preparer._bindparam_requires_quotes(name): @@ -346,7 +333,27 @@ class OracleDialect_cx_oracle(OracleDialect): execution_ctx_cls = OracleExecutionContext_cx_oracle statement_compiler = OracleCompiler_cx_oracle driver = "cx_oracle" - colspecs = colspecs + + colspecs = colspecs = { + sqltypes.Numeric: _OracleNumeric, + sqltypes.Date : _OracleDate, # generic type, assume datetime.date is desired + oracle.DATE: oracle.DATE, # non generic type - passthru + sqltypes.LargeBinary : _OracleBinary, + sqltypes.Boolean : oracle._OracleBoolean, + sqltypes.Interval : _OracleInterval, + oracle.INTERVAL : _OracleInterval, + sqltypes.Text : _OracleText, + sqltypes.String : _OracleString, + sqltypes.UnicodeText : _OracleUnicodeText, + sqltypes.CHAR : _OracleChar, + sqltypes.Integer : _OracleInteger, # this is only needed for OUT parameters. + # it would be nice if we could not use it otherwise. + oracle.NUMBER : oracle.NUMBER, # don't let this get converted + oracle.RAW: _OracleRaw, + sqltypes.Unicode: _OracleNVarChar, + sqltypes.NVARCHAR : _OracleNVarChar, + } + execute_sequence_format = list diff --git a/test/sql/test_types.py b/test/sql/test_types.py index ba7b2aaead..6a58d180cc 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -1110,29 +1110,29 @@ class NumericTest(TestBase): def test_numeric_as_decimal(self): self._do_test( Numeric(precision=8, scale=4), - [15.7563, Decimal("15.7563")], - [Decimal("15.7563")], + [15.7563, Decimal("15.7563"), None], + [Decimal("15.7563"), None], ) def test_numeric_as_float(self): if testing.against("oracle+cx_oracle"): - filter_ = lambda n:round(n, 5) + filter_ = lambda n:n is not None and round(n, 5) or None else: filter_ = None self._do_test( Numeric(precision=8, scale=4, asdecimal=False), - [15.7563, Decimal("15.7563")], - [15.7563], + [15.7563, Decimal("15.7563"), None], + [15.7563, None], filter_ = filter_ ) def test_float_as_decimal(self): self._do_test( Float(precision=8, asdecimal=True), - [15.7563, Decimal("15.7563")], - [Decimal("15.7563")], - filter_ = lambda n:round(n, 5) + [15.7563, Decimal("15.7563"), None], + [Decimal("15.7563"), None], + filter_ = lambda n:n is not None and round(n, 5) or None ) def test_float_as_float(self): @@ -1140,26 +1140,20 @@ class NumericTest(TestBase): Float(precision=8), [15.7563, Decimal("15.7563")], [15.7563], - filter_ = lambda n:round(n, 5) + filter_ = lambda n:n is not None and round(n, 5) or None ) def test_precision_decimal(self): numbers = set([ decimal.Decimal("54.234246451650"), - decimal.Decimal("87673.594069654000"), decimal.Decimal("0.004354"), decimal.Decimal("900.0"), ]) - if testing.against('sqlite', 'sybase+pysybase', 'oracle+cx_oracle'): - filter_ = lambda n:round_decimal(n, 11) - else: - filter_ = None self._do_test( Numeric(precision=18, scale=12), numbers, numbers, - filter_=filter_ ) def test_enotation_decimal(self): @@ -1192,6 +1186,7 @@ class NumericTest(TestBase): @testing.fails_on("sybase+pyodbc", "Don't know how do get these values through FreeTDS + Sybase") + @testing.fails_on("firebird", "Precision must be from 1 to 18") def test_enotation_decimal_large(self): """test exceedingly large decimals. @@ -1212,13 +1207,15 @@ class NumericTest(TestBase): @testing.fails_on('sqlite', 'TODO') @testing.fails_on('oracle', 'TODO') @testing.fails_on('postgresql+pg8000', 'TODO') + @testing.fails_on("firebird", "Precision must be from 1 to 18") def test_many_significant_digits(self): numbers = set([ decimal.Decimal("31943874831932418390.01"), decimal.Decimal("319438950232418390.273596"), + decimal.Decimal("87673.594069654243"), ]) self._do_test( - Numeric(precision=26, scale=6), + Numeric(precision=38, scale=12), numbers, numbers )