#6184 closed (invalid)
encoding conversion breaks floating-point placeholders in raw PostgreSQL queries
Reported by: | Chris Chamberlin | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
SVN revision 6903 rejects queries using floating-point values and placeholders:
>>> from django.db import connection >>> c=connection.cursor() >>> c.execute('SELECT * from my_table where floatfield > %f',[1]) # ints work fine >>> c.execute('SELECT * from my_table where floatfield > %f',[0.1]) Traceback (most recent call last): File "<stdin>", line 1, in ? File "django/db/backends/util.py", line 18, in execute File "django/db/backends/postgresql/base.py", line 47, in execute TypeError: float argument required
This is a regression from sometime between revision 4926 and 6903; sorry I can't be more specific.
The attached patch fixes this by modifying django.utils.encoding.smart_str() to really convert only instances of basestring when strings_only is true.
Attachments (1)
Change History (5)
by , 17 years ago
comment:1 by , 17 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 17 years ago
If this does turn out to be a genuine problem, the patch is not correct at all. It is very important that most objects are passed through the unicode() path, since they know how to turn themselves into strings correctly. The "strings_only" whitelist is a list of exceptions for certain native Python types only that for technical reasons should be kept as their native types (each one has a specific reason). Changing that would break the object-oriented behaviour of Python.
follow-up: 4 comment:3 by , 17 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Adaptation of Python values to SQL types: ... The variables placeholder must always be a %s, even if a different placeholder (such as a %d for an integer) may look more appropriate.
comment:4 by , 17 years ago
Aha. Thanks.
Just for completeness in case someone else comes across this: I'm still using psycopg 1.x, and does apparently support the %d and %f placeholders; this change to support %s only is noted in psycopg's Migration from psycopg 1 to 2 documentation. However, using %s fixes the problem in psycopg1 as well, and is a perfectly reasonable workaround given that it's an old version of the adapter.
I can't reproduce the problem. What postgres adapter are you using (postgres or psycopg2)?.
For me (psycopg2) it fails for ints, too:
If I use %s instead of %f it works:
At least for psycopg2 smart_str() (which changed in the patch) is not called.
I modified it to throw an AssertionError and the result was the same.
I looked at the code of the old postgres adapter. Here the paramters get converted:
Maybe it is enough to add float to the isinstance test at the beginning of smart_str.