Author: phd
Date: 2008-07-01 10:27:44 -0600 (Tue, 01 Jul 2008)
New Revision: 3498
Modified:
SQLObject/trunk/docs/News.txt
SQLObject/trunk/docs/SQLObject.txt
SQLObject/trunk/sqlobject/col.py
SQLObject/trunk/sqlobject/tests/test_decimal.py
Log:
DecimalStringCol - similar to DecimalCol but stores data as strings to
work around problems in some drivers and type affinity problem in SQLite.
Modified: SQLObject/trunk/docs/News.txt
===================================================================
--- SQLObject/trunk/docs/News.txt 2008-07-01 16:26:34 UTC (rev 3497)
+++ SQLObject/trunk/docs/News.txt 2008-07-01 16:27:44 UTC (rev 3498)
@@ -30,6 +30,9 @@
* Use reversed() in manager/command.py instead of .__reversed__().
+* DecimalStringCol - similar to DecimalCol but stores data as strings to
+ work around problems in some drivers and type affinity problem in SQLite.
+
SQLObject 0.10.2
================
Modified: SQLObject/trunk/docs/SQLObject.txt
===================================================================
--- SQLObject/trunk/docs/SQLObject.txt 2008-07-01 16:26:34 UTC (rev 3497)
+++ SQLObject/trunk/docs/SQLObject.txt 2008-07-01 16:27:44 UTC (rev 3498)
@@ -1135,6 +1135,10 @@
.. _`type affinity`: http://sqlite.org/datatype3.html#affinity
+`DecimalStringCol`:
+ Similar to `DecimalCol` but stores data as strings to work around
+ problems in some drivers and type affinity problem in SQLite.
+
`EnumCol`:
One of several string values -- give the possible strings as a
list, with the `enumValues` keyword argument. MySQL has a native
Modified: SQLObject/trunk/sqlobject/col.py
===================================================================
--- SQLObject/trunk/sqlobject/col.py 2008-07-01 16:26:34 UTC (rev 3497)
+++ SQLObject/trunk/sqlobject/col.py 2008-07-01 16:27:44 UTC (rev 3498)
@@ -1346,6 +1346,44 @@
baseClass = SOCurrencyCol
+class DecimalStringValidator(DecimalValidator):
+ def from_python(self, value, state):
+ if value is None:
+ return None
+ if isinstance(value, sqlbuilder.SQLExpression):
+ return value
+ if not isinstance(value, basestring):
+ value = str(value)
+ connection = state.soObject._connection
+ if hasattr(connection, "decimalSeparator"):
+ value = value.replace(connection.decimalSeparator, ".")
+ try:
+ Decimal(value) # Test if the value is valid
+ except:
+ raise validators.Invalid("can not parse Decimal value '%s' in the DecimalCol from '%s'" %
+ (value, getattr(state, 'soObject', '(unknown)')), value, state)
+ else:
+ return value
+
+class SODecimalStringCol(SOStringCol):
+ def __init__(self, **kw):
+ size = kw.pop('size', NoDefault)
+ assert size is not NoDefault, \
+ "You must give a size argument"
+ precision = kw.pop('precision', NoDefault)
+ assert precision is not NoDefault, \
+ "You must give a precision argument"
+ kw['length'] = size + precision
+ super(SODecimalStringCol, self).__init__(**kw)
+
+ def createValidators(self):
+ return [DecimalStringValidator()] + \
+ super(SODecimalStringCol, self).createValidators()
+
+class DecimalStringCol(StringCol):
+ baseClass = SODecimalStringCol
+
+
class BinaryValidator(validators.Validator):
"""
Validator for binary types.
Modified: SQLObject/trunk/sqlobject/tests/test_decimal.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_decimal.py 2008-07-01 16:26:34 UTC (rev 3497)
+++ SQLObject/trunk/sqlobject/tests/test_decimal.py 2008-07-01 16:27:44 UTC (rev 3498)
@@ -8,23 +8,24 @@
class DecimalTable(SQLObject):
col1 = DecimalCol(size=6, precision=4)
+ col2 = DecimalStringCol(size=6, precision=4)
if supports('decimalColumn'):
- def test_1decimal():
- """Tests new instance with a float in col1."""
+ def test_1_decimal():
setupClass(DecimalTable)
- d = DecimalTable(col1=21.12)
+ d = DecimalTable(col1=21.12, col2='10.01')
# psycopg2 returns float as Decimal
if isinstance(d.col1, Decimal):
assert d.col1 == Decimal("21.12")
else:
assert d.col1 == 21.12
+ assert d.col2 == Decimal("10.01")
- def test_2Decimal():
- """Tests new instance with a Decimal in col1."""
+ def test_2_decimal():
setupClass(DecimalTable)
- d = DecimalTable(col1=Decimal("21.12"))
+ d = DecimalTable(col1=Decimal("21.12"), col2=Decimal('10.01'))
if isinstance(d.col1, Decimal):
assert d.col1 == Decimal("21.12")
else:
assert d.col1 == 21.12
+ assert d.col2 == Decimal("10.01")
|