Michael Bayer wrote:
Chris Withers wrote:
Michael Bayer wrote:
Has anyone (hi, list, talking to you too!) already done a custom type
for this specific problem?
people do custom types for all sorts of things.  In the case of the
Decimal here I'd likely subclass sqlalchemy.databases.sqlite.SLNumeric
which should ensure that your own bind_processor() and
result_processor()
methods can be called.
Okay, but how do I make sure this is only used when sqlite this the
engine?

You can use a TypeDecorator to switch between implementations.  I had a
plan to add a pre-fab type for this to core that allows easy switching of
implementations.

Okay, this is what I've ended up with for this one:

from decimal import Decimal
from sqlalchemy import types
from sqlalchemy.databases.sqlite import SQLiteDialect

class Numeric(types.TypeDecorator):
    """A numeric type that respects precision with SQLite

    - always returns Decimals
    - always rounds as necessary as a result
    """

    impl = types.Numeric

    def bind_processor(self, dialect):
        if isinstance(dialect,SQLiteDialect):
            def process(value):
                if value is None:
                    return None
                else:
                    return float(value)
            return process
        else:
            return super(Numeric,self).bind_processor(dialect)

    def result_processor(self, dialect):
        if isinstance(dialect,SQLiteDialect):
            fstring = "%%.%df" % self.impl.scale
            def process(value):
                if value is None:
                    return None
                else:
                    return Decimal(fstring % value)
            return process
        else:
            return super(Numeric,self).result_processor(dialect)

What should I have done differently and why?

cheers,

Chris

PS: While looking into how to do this for 0.5.8, I saw this dire warning in 0.6:

util.warn("Dialect %s+%s 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." %
                            (dialect.name, dialect.driver))

...which I also saw applies to SQLite.

What are the "rounding errors and others issues" that you allude to?
What is the integer/string recommendation saying? Use a String column? Use an Integer column? Is this something I could work into a TypeDecorator? Should I?

cheers,

Chris

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to