On Tue, Nov 3, 2009 at 6:46 PM, Russell Keith-Magee
<[email protected]> wrote:
>
> On Wed, Nov 4, 2009 at 3:05 AM, Bill Freeman <[email protected]> wrote:
>>
>> On Tue, Nov 3, 2009 at 9:14 AM, Bill Freeman <[email protected]> wrote:
>>> On Tue, Nov 3, 2009 at 7:05 AM, Russell Keith-Magee
>>> <[email protected]> wrote:
>>>>
>>>> On Tue, Nov 3, 2009 at 12:19 PM, Christophe Pettus <[email protected]> 
>>>> wrote:
>>>>>
>>>>>
>>>>> On Nov 2, 2009, at 2:14 PM, Bill Freeman wrote:
>>>>>> My presumption is that the older PostgreSQL, expecting to have to
>>>>>> decide whether unquoted things are strings (e.g.; "status" in the
>>>>>> query samples above), used to look at the context and decided that we
>>>>>> had meant the 8 as a string.
>>>>>
>>>>> In particular, as of PostgreSQL 8.3 (and thus 8.4), non-text types are
>>>>> not automatically cast to text.  You can find the details in the 8.3
>>>>> release notes:
>>>>>
>>>>>        http://www.postgresql.org/docs/8.3/static/release-8-3.html
>>>>>
>>>>> The relevant section is E.9.2.1.
>>>>>
>>>>>> Thoughts?  Workaround suggestions?
>>>>>
>>>>> I'm not completely sure why the ORM is generating SQL that compares a
>>>>> number with a character string in the first place; that sounds like a
>>>>> bug in either the ORM or the client code, to me.
>>>>
>>>> I concur. This looks like it might be a Django bug.
>>>>
>>>> If I understand the original problem correctly, it is this:
>>>>
>>>> class MyObj(models.Model):
>>>>    CHOICES = (
>>>>        ('1', 'first choice')
>>>>        ('2', 'second choice')
>>>>    )
>>>>    choice = models.CharField(max_length=1, choices=CHOICES)
>>>>
>>>> Now run two queries. First, query using an integer:
>>>>
>>>> MyObj.objects.filter(choice=1)
>>>>
>>>> This yields the SQL:
>>>>
>>>> ('SELECT `myapp_myobj`.`id`, `myapp_myobj`.`choice` FROM `myapp_myobj`
>>>> WHERE `myapp_myobj`.`choice` = %s ', (1,))
>>>>
>>>> Now, query with an actual string:
>>>>
>>>> MyObj.objects.filter(choice='1')
>>>>
>>>> which yields the SQL:
>>>>
>>>> ('SELECT `myapp_myobj`.`id`, `myapp_myobj`.`choice` FROM `myapp_myobj`
>>>> WHERE `myapp_myobj`.`choice` = %s ', ('1',))
>>>
>>> Might that have to be:
>>>
>>>    'SELECT ... `choice` = `%s`', ('1',))
>>>
>>> because %s renders both 1 and '1' as the single character 1.
>>>
>>> But then, if I understand correctly, by the time this gets to the DB
>>> it's actually something like:
>>>   SELECT ... = ? '
>>>
>>> and I don't know how the quoting works there.  Still that's the
>>> province of the adaptor, and all django can do is decide what is
>>> passed to psycopg2.  I guess I'm going to learn more about the DB
>>> adaptor.
>>>>
>>>> The fact that the first example (the integer lookup) passes at all is
>>>> due to the good grace of the databases themselves - logically, I think
>>>> Postgres 8.4 is correct in declaring this an error. "1" != 1.
>>>>
>>>> I think the fix is pretty simple. CharField doesn't currently have a
>>>> get_db_prep_value() method, and it should.
>>>>
>>>> Compare and contrast with IntegerField or BooleanField - both these
>>>> fields have get_db_prep_value() methods that cast the provided value
>>>> to int() and bool(). CharField (and TextField for that matter) should
>>>> do the same, but with unicode(). This would force the filter value of
>>>> 1 into '1', which will be passed to the backend as a string, as it
>>>> should be.
>>>>
>>>> I've just opened ticket #12137 to track this. I've put it on the 1.2
>>>> milestone, so we will endeavour to fix it before we hit v1.2. Any
>>>> assistance in turning the example and suggested fix into a trunk-ready
>>>> patch will be gratefully accepted.
>>>
>>> Since this is impacting me right now, I'll spend some quality time
>>> with pdb to try and come up with a patch.
>>>
>>> News at it happens.
>>>>
>>>> Yours,
>>>> Russ Magee %-)
>>>
>>> Bill
>>>
>>
>> Well, adding the obvious get_db_prep_value()  (thanks Russ) to both
>> CharField and TextField in django/db/models/fields/__init__.py makes
>> my app work on ps8.4 without any ill effects on pg8.1.11.  I've tested
>> most of the page types that I have in both circumstances without
>> noticing any anomalies.
>>
>> Of course that doesn't prove that there's nobody who depends on the
>> old behavior.
>>
>> I basically copied the version from BooleanField, and changed the
>> "return bool(value)" to "return unicode(value)" (though everything
>> else inside the queryset's query object seems to be string rather than
>> unicode, so I'm not positive that "return str(value)" isn't more self
>> consistent).
>>
>> I'll try to provide something more formal as a response to the ticket.
>
> Hi Bill,
>
> Thanks for taking the time to check this and make a patch. There are
> two things standing between this and the trunk.
>
> * Generate your diff against the root of the tree, not as a diff
> between two versions of a single file. The output of `svn diff`` is
> ideal.
>
> * Tests! Tests! Tests! A patch is great, but it needs to be tested.
> The regressiontests.queries tests looks to be as good a place as any.
> The queries test already contains a bunch of models that look like
> they could be used to test this (you just need to do an integer lookup
> on a CharField).
>
> I'm going to have to do both of these things before the fix gets into
> trunk, but if you can spare the time to do the leg work, the fix will
> end up in trunk much sooner.
>
> Yours,
> Russ Magee %-)
>

Russ,

I figured that I would diff what I had an opportunity to test on the
configurations I have available.

I'll try to figure out more later, but for now this has made other
stuff slip, so it will be a while.

So I'll check the ticket from time to time, and if I see that you've
done it, I'll breath a sigh of relief.  Otherwise, if I get ahead
enough to give it some time, I will.

Bill

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected]
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