"""
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)
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
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):
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
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):
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):
@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.
@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
)