mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-29 20:14:55 -04:00
Merge "Coerce float Python type to Float; ensure Python float coming back"
This commit is contained in:
Vendored
+14
@@ -13,6 +13,20 @@
|
||||
.. changelog::
|
||||
:version: 1.2.0b1
|
||||
|
||||
.. change:: 4017
|
||||
:tags: bug, sql
|
||||
:tickets: 4017
|
||||
|
||||
Added some extra strictness to the handling of Python "float" values
|
||||
passed to SQL statements. A "float" value will be associated with the
|
||||
:class:`.Float` datatype and not the Decimal-coercing :class:`.Numeric`
|
||||
datatype as was the case before, eliminating a confusing warning
|
||||
emitted on SQLite as well as unecessary coercion to Decimal.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`change_floats_12`
|
||||
|
||||
.. change:: 3058
|
||||
:tags: feature, orm
|
||||
:tickets: 3058
|
||||
|
||||
Vendored
+25
@@ -764,6 +764,31 @@ Where the value of the parameter "x_1" is ``'total/%score'``.
|
||||
|
||||
:ticket:`2694`
|
||||
|
||||
.. _change_floats_12:
|
||||
|
||||
Stronger typing added to "float" datatypes
|
||||
------------------------------------------
|
||||
|
||||
A series of changes allow for use of the :class:`.Float` datatype to more
|
||||
strongly link itself to Python floating point values, instead of the more
|
||||
generic :class:`.Numeric`. The changes are mostly related to ensuring
|
||||
that Python floating point values are not erroneously coerced to
|
||||
``Decimal()``, and are coerced to ``float`` if needed, on the result side,
|
||||
if the application is working with plain floats.
|
||||
|
||||
* A plain Python "float" value passed to a SQL expression will now be
|
||||
pulled into a literal parameter with the type :class:`.Float`; previously,
|
||||
the type was :class:`.Numeric`, with the default "asdecimal=True" flag, which
|
||||
meant the result type would coerce to ``Decimal()``. In particular,
|
||||
this would emit a confusing warning on SQLite::
|
||||
|
||||
float_value = connection.scalar(
|
||||
select([literal(4.56)]) # the "BindParameter" will now be
|
||||
# Float, not Numeric(asdecimal=True)
|
||||
)
|
||||
|
||||
:ticket:`4017`
|
||||
|
||||
Key Behavioral Changes - ORM
|
||||
============================
|
||||
|
||||
|
||||
@@ -2604,7 +2604,7 @@ MATCHTYPE = MatchType()
|
||||
|
||||
_type_map = {
|
||||
int: Integer(),
|
||||
float: Numeric(),
|
||||
float: Float(),
|
||||
bool: BOOLEANTYPE,
|
||||
decimal.Decimal: Numeric(),
|
||||
dt.date: Date(),
|
||||
|
||||
@@ -431,6 +431,24 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
|
||||
filter_=lambda n: n is not None and round(n, 5) or None
|
||||
)
|
||||
|
||||
@testing.fails_on("mysql", "until we do #4020")
|
||||
def test_float_coerce_round_trip(self):
|
||||
expr = 15.7563
|
||||
|
||||
val = testing.db.scalar(
|
||||
select([literal(expr)])
|
||||
)
|
||||
eq_(val, expr)
|
||||
|
||||
# TODO: this one still breaks on MySQL
|
||||
# def test_decimal_coerce_round_trip(self):
|
||||
# expr = decimal.Decimal("15.7563")
|
||||
#
|
||||
# val = testing.db.scalar(
|
||||
# select([literal(expr)])
|
||||
# )
|
||||
# eq_(val, expr)
|
||||
|
||||
@testing.requires.precision_numerics_general
|
||||
def test_precision_decimal(self):
|
||||
numbers = set([
|
||||
|
||||
@@ -2025,6 +2025,23 @@ class ExpressionTest(
|
||||
expr = column('foo', CHAR) == "asdf"
|
||||
eq_(expr.right.type.__class__, CHAR)
|
||||
|
||||
def test_actual_literal_adapters(self):
|
||||
for data, expected in [
|
||||
(5, Integer),
|
||||
(2.65, Float),
|
||||
(True, Boolean),
|
||||
(decimal.Decimal("2.65"), Numeric),
|
||||
(datetime.date(2015, 7, 20), Date),
|
||||
(datetime.time(10, 15, 20), Time),
|
||||
(datetime.datetime(2015, 7, 20, 10, 15, 20), DateTime),
|
||||
(datetime.timedelta(seconds=5), Interval),
|
||||
(None, types.NullType)
|
||||
]:
|
||||
is_(
|
||||
literal(data).type.__class__,
|
||||
expected
|
||||
)
|
||||
|
||||
def test_typedec_operator_adapt(self):
|
||||
expr = test_table.c.bvalue + "hi"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user