float should coerce to Float

Issue #4017 resolved
Mike Bayer repo owner created an issue

it seems to be ancient history that we slowly added support for Decimal, but never changed the coercion of plain "float" to be Float, not Numeric w/ decimals:

_type_map = {
    int: Integer(),
    float: Numeric(),
    bool: BOOLEANTYPE,
    decimal.Decimal: Numeric(),
    dt.date: Date(),
    dt.datetime: DateTime(),
    dt.time: Time(),
    dt.timedelta: Interval(),
    util.NoneType: NULLTYPE
}

So the more expensive Decimal is added into situations where plain float is used, and also on SQLite we of course get the warning as well as the wrong type back:

from sqlalchemy import create_engine, literal, select

e = create_engine("sqlite://")

print repr(e.scalar(select([literal(4.56)])))
#!


$ python test.py 
/home/classic/dev/sqlalchemy/lib/sqlalchemy/sql/sqltypes.py:596: SAWarning: Dialect sqlite+pysqlite does *not* support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.
  'storage.' % (dialect.name, dialect.driver))
Decimal('4.5600000000')

ouch!

this is easy to fix, but may or may not have hard implications for current applications. Consider for 1.2 if possible.

Comments (4)

  1. Mike Bayer reporter

    also noted that MySQL is not always giving us "float" back in a round trip, so the patch considers also adding "float" coercion if we know that's the datatype we expect. this gerrit probably needs migration notes for 1.2 and might need some more tests and even more coercions since we still don't have consistent round trips in all cases.

  2. Mike Bayer reporter

    note the gerrit should be broken into two separate issues and likely a new bug report here for the MySQL issue

  3. Mike Bayer reporter

    Coerce float Python type to Float; ensure Python float coming back

    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.

    Change-Id: I1bb1810ff1d198c0d929ccba5656e55401d74119 Fixes: #4017

    → <<cset 1776597131ef>>

  4. Log in to comment