Hi again Malcolm,
I've now performed some of the test you suggest here, and I would like
to report my findings.

> > It seems to me that when the Python renderer sees the Decimal() call,
> > it goes and fetches my OS locale, which calls for Swedish decimal
> > commas instead of US decimal points.
>
> This doesn't seem to be the case from looking at the source. The decimal
> module in Python is purely Python code and it doesn't call any of the
> locale functions

Yes, you are right. According to my findings reported below, it is not
the Decimal that is causing my problem. It rather seems to be
something happening deeper in the pymssql code while the value
rendered as Decimal is processed.

> I'd personally be a little suspicious of what the database backend is
> doing. Is the type of your id column really something that can only be
> represented by a Decimal() class? Because if it's an integer, the db
> backend should be returning an integer there (that's a secondary bug,
> but it makes me suspicious about what else is going on).

The table value type is BIGINT, and as I learned from the pymssql
documentation this is rendered as a Decimal.

> Try comparing the output of locale.localeconv() before and after you
> make the call to the database, for example. It shouldn't change and
> everything should be operating in the C locale (since the external
> locale of your system isn't applied unless something calls
> locale.setlocale(locale.LC_ALL, '')). I could imagine some code that
> tries to be "helpful" and changes the locale for whatever reason and
> messes everything else up.

OK, so now I checked on the locale before and after the database call
and also checked with a hardcoded list emulating the return values
from the database call, including the Decimal. As far as I can see
there was NO changes in locale in either case, and the hardcoded
Decimal didn't affect the behaviour of the template floatformat. So my
assumption that Decimal affects the locale is thus wrong (as I believe
you have been trying to tell me all the time).

Here is a list of test outputs on my web page for various scenarios:

Before database call
--------------------
>From database: []

Locale: {'mon_decimal_point': '', 'int_frac_digits': 127,
'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '',
'n_sign_posn': 127, 'decimal_point': '.', 'int_curr_symbol': '',
'n_cs_precedes': 127, 'p_sign_posn': 127,
'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '',
'n_sep_by_space': 127, 'mon_grouping': [],
'p_cs_precedes': 127, 'positive_sign': '', 'grouping': []}

Hardcoded variable: 678.9

Hardcoded variable through floatformat: 678.9

After database call
--------------------
>From database: [(Decimal("27164771"), 27, 16, 7.77128,
9.2557200000000002, 2006, 'Quantum dynamics of a d-wave Josephson
junction', 3, 30.0, '000234546300030', 17.601243339253998, '@', 7)]

Locale: {'mon_decimal_point': '', 'int_frac_digits': 127,
'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '',
'n_sign_posn': 127, 'decimal_point': '.', 'int_curr_symbol': '',
'n_cs_precedes': 127, 'p_sign_posn': 127,
'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '',
'n_sep_by_space': 127, 'mon_grouping': [],
'p_cs_precedes': 127, 'positive_sign': '', 'grouping': []}

Hardcoded variable: 678,90 (sending 668.90 raises template error in
floatformat)

Hardcoded variable through floatformat:


After hardcoded results list
----------------------------
Hardcoded: [(Decimal("27164771"), 27, 16, 7.77128, 9.2557200000000002,
2006, 'Quantum dynamics of a d-wave Josephson junction', 3, 30.0,
'000234546300030', 17.601243339253998, '@', 7)]

Locale: {'mon_decimal_point': '', 'int_frac_digits': 127,
'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '',
'n_sign_posn': 127, 'decimal_point': '.', 'int_curr_symbol': '',
'n_cs_precedes': 127, 'p_sign_posn': 127,
'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '',
'n_sep_by_space': 127, 'mon_grouping': [],
'p_cs_precedes': 127, 'positive_sign': '', 'grouping': []}

Hardcoded variable through: 678.90

Hardcoded variable through floatformat: 678.9

After doing those tests, I realised that if our database BIGINT was a
problem for pymssql, I could try to change the data type for the value
returned. So I convoluted the record ID in a Transact-SQL CAST
statement, converting it to a INT and then I got a proper integer
returned and all my problems went away. Here is the web page result:

After doing CAST AS INT
-----------------------
SQL: SELECT CAST(Artikel.ID AS INT), ... FROM Artikel ...

>From database: [(27164771, 27, 16, 7.77128, 9.2557200000000002, 2006,
'Quantum dynamics of a d-wave Josephson junction', 3, 30.0,
'000234546300030', 17.601243339253998, '@', 7)]

Locale: {'mon_decimal_point': '', 'int_frac_digits': 127,
'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '',
'n_sign_posn': 127, 'decimal_point': '.', 'int_curr_symbol': '',
'n_cs_precedes': 127, 'p_sign_posn': 127,
'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '',
'n_sep_by_space': 127, 'mon_grouping': [],
'p_cs_precedes': 127, 'positive_sign': '', 'grouping': []}

Hardcoded variable: 678.90

Hardcoded variable through floatformat: 678.9


> In fact, ideally, don't even use Django at all here. You know the line
> of code that is failing, so you can probably just write a 10 line
> program that reads something from the database and then executes a
> similar line and make sure it fails similarly. Then do the same thing
> but without the database (just hard-coded data).
>
> At the moment, it looks very much to me like something in this
> non-Django code is messing up your system environment. The decimal
> module in Python is very portable and nothing in it or Django attempts
> to change the running locale (which means it will always be 'C'). I
> think you're looking in the wrong place for the bug at the moment --
> where the traceback is raced is a consequence of the problem, not the
> source.

Yes. As you can see above, you are right.

I have now worked around my acute problem, but I'll try to find some
time to dig deeper into this, making code that not uses Django at all
as you suggest, but it will take me some time to do that. I'll return
with a report on that later.

Thanks for your help,
Ulf
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to