From: Murat O. <mur...@is...> - 2005-10-19 18:29:52
Attachments:
DecimalValidator.py
|
Hi, I'm still playing with sqlobject. Personally I dislike to get strings in place of decimal columns. So I inserted attached code between DateCol and SODecimalCol in col.py. I also added createValidators method to SODecimalCol wiich is very similar to createValidators method of SOFloatCol. Since I'm not a Python guru, a more efficient code is surely possible. Please take this code as a humble approach to the problem, and I would be very appreciated if someone criticize it. I also would like to know whether other methods are existed to get same result. Regards, Murat Ozsoyler |
From: Murat O. <mur...@is...> - 2005-11-09 19:07:36
Attachments:
col.py
mssqlconnection.py
|
Hi, As I told before I don't like obtaining strings or unicodes in place of decimal.Decimals or at least floats. Since DecimalCols contains values to be used in arithmetic expressions it is cumbersome to convert them to numeric types. Even worse, adodb returns decimal points according to local settings, so one sould replace the decimal separator with dot before converting it to a numeric type. In my first attempt I queried locale module to obtain local decimal separator character. This approach loaded the burden of setting default locale for the application before importing sqlobject on the programmer. This was cumbersome. In this version, MSSQLConnection queries the decimal separator and set a member variable. Then when DecimalValidator is being instantiated, the value of this variable is passed (if the connection object has this attribute) to the constructor. Also if decimal module is not present float is used instead. I can not test this feature though. I examined the test_decimal.py and couldn't see any thing that conflicts with this version of DecimalCol but I've not tested it. I'll ask questions about tests in a new thread. The col.py and mssqlconnection.py which are changed by me are attached. I appreciate any comments about these patches. Regards, Murat Ozsoyler |
From: Oleg B. <ph...@ph...> - 2005-11-18 19:52:05
|
Hello! Sorry it took so long... On Wed, Nov 09, 2005 at 08:59:44PM +0200, Murat Ozsoyler wrote: > As I told before I don't like obtaining strings or unicodes in place of > decimal.Decimals or at least floats. Since DecimalCols contains values > to be used in arithmetic expressions it is cumbersome to convert them to > numeric types. Even worse, adodb returns decimal points according to > local settings, so one sould replace the decimal separator with dot > before converting it to a numeric type. > > In my first attempt I queried locale module to obtain local decimal > separator character. This approach loaded the burden of setting default > locale for the application before importing sqlobject on the programmer. > This was cumbersome. > > In this version, MSSQLConnection queries the decimal separator and set a > member variable. Then when DecimalValidator is being instantiated, the > value of this variable is passed (if the connection object has this > attribute) to the constructor. > > Also if decimal module is not present float is used instead. I can not > test this feature though. > > I examined the test_decimal.py and couldn't see any thing that conflicts > with this version of DecimalCol but I've not tested it. I'll ask > questions about tests in a new thread. > > The col.py and mssqlconnection.py which are changed by me are attached. > I appreciate any comments about these patches. I applied the patch, but alas! - it does not pass the test! :( It seems the problem is here: def createValidators(self): if hasattr(self.soClass._connection, "decimalSeparator"): ^^^^^^^^^^^^^^^^^^^^^^^^ but I am not sure what the problem is. The test failed with the error: def createValidators(self): > if hasattr(self.soClass._connection, "decimalSeparator"): [/home/phd/work/SQLObject/SQLObject-trunk/sqlobject/col.py:1177] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __get__(self, obj, type=None): # I'm a little surprised we have to do this, but apparently # the object's private dictionary of attributes doesn't # override this descriptor. if obj and obj.__dict__.has_key('_connection'): return obj.__dict__['_connection'] > return self.getConnection() [/home/phd/work/SQLObject/SQLObject-trunk/sqlobject/dbconnection.py:906] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def getConnection(self): try: return self.threadingLocal.connection except AttributeError: try: return self.processConnection except AttributeError: raise AttributeError( "No connection has been defined for this thread " E "or process") > AttributeError: No connection has been defined for this thread or process [/home/phd/work/SQLObject/SQLObject-trunk/sqlobject/dbconnection.py:918] Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2005-11-21 18:30:45
|
On Wed, Nov 09, 2005 at 08:59:44PM +0200, Murat Ozsoyler wrote: > The col.py and mssqlconnection.py which are changed by me are attached. > I appreciate any comments about these patches. I fixed problems and applied to the trunk, revision 1313. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2005-10-19 18:49:31
|
On Wed, Oct 19, 2005 at 09:24:53PM +0300, Murat Ozsoyler wrote: > I'm still playing with sqlobject. Personally I dislike to get strings in > place of decimal columns. So I inserted attached code between DateCol > and SODecimalCol in col.py. Thank you! > I also added createValidators method to > SODecimalCol wiich is very similar to createValidators method of SOFloatCol. Have you tested it? IWBN if you extend test_decimal.py to include tests for all data types the code handles. # adodb uses locale decimal separator, so locale settings should be set # by calling locale.setlocale(LC_ALL, "") decimal_separator = locale.localeconv()["decimal_point"] What if one haven't called locale.setlocale(LC_ALL, "")? Will the above line raise an exception or what? if isinstance(value, (int, long, decimal.Decimal, sqlbuilder.SQLExpression)): Module "decimal" is not available in Python 2.2 and 2.3; SQLObject support Python 2.2 to 2.4... if isinstance(value, types.FloatType): Why not if isinstance(value, float): ? Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Murat O. <mur...@is...> - 2005-10-19 21:00:32
|
Hi Oleg, Thank you for answering. Oleg Broytmann wrote: > Have you tested it? IWBN if you extend test_decimal.py to include tests > for all data types the code handles. I have tested it and see both gets and sets for DecimalCols work correctly. But I haven't used sqlobject test procedure yet. I'll work on it in the weekend, I hope. > > # adodb uses locale decimal separator, so locale settings should be set > # by calling locale.setlocale(LC_ALL, "") > decimal_separator = locale.localeconv()["decimal_point"] > > What if one haven't called locale.setlocale(LC_ALL, "")? Will the above > line raise an exception or what? I use MSSQL and adodbapi. Also default locale of my system is 'Turkish_Turkey.1254' of which the decimal separator is comma. Decimal column values return strings (actually unicodes) of this form: '1234,56' for the value 1234.56 as shown in the query analyzer. This shows us that mssql oledb driver replaces decimal points with locale decimal separator of the system. If default locale of your system uses dot character for decimal separator there is no problem, otherwise you should replace your locale's decimal separator with dot in order to be able to convert the value to Decimal. Whether other database drivers do the same behaviour and how it can be detected is another issue. May be a method to detect this can be added to DBAPI which is overriden by the ancestor classes. Using "select cast('1234.56' as decimal(10, 2))" query for mssql and test the returned value for the decimal separator can do the trick. This overcomes the necessity for locale module. > > if isinstance(value, (int, long, decimal.Decimal, sqlbuilder.SQLExpression)): > > Module "decimal" is not available in Python 2.2 and 2.3; SQLObject > support Python 2.2 to 2.4... It can be tested and fall back to float type when the Python version is older than 2.4. Personally I don't like the numeric column values represented as strings because those columns are intended to be used in arithmetic expressions and converting them everytime is cumbersome. > > if isinstance(value, types.FloatType): > > Why not > if isinstance(value, float): > ? Just because I've already imported types module for some other reason and first form is more verbose. Second form is not invalid of course (and may be more efficient). > > Oleg. Regards, Murat Ozsoyler |
From: Oleg B. <ph...@ph...> - 2005-10-20 09:28:23
|
On Wed, Oct 19, 2005 at 11:55:29PM +0300, Murat Ozsoyler wrote: > I have tested it and see both gets and sets for DecimalCols work > correctly. But I haven't used sqlobject test procedure yet. I'll work on > it in the weekend, I hope. Ok, waiting... > > Module "decimal" is not available in Python 2.2 and 2.3; SQLObject > >support Python 2.2 to 2.4... > It can be tested and fall back to float type when the Python version is > older than 2.4. Please do the test... Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |