MySQLdb select

Sibylle Koczian Sibylle.Koczian at Bibliothek.Uni-Augsburg.de
Thu Aug 5 08:09:23 EDT 2004


Dennis Lee Bieber schrieb:
> 
> 	Except that the conversion function, .literal(),  /does/  accept
> a single item, a sequence (tuple OR list), or a mapping (dictionary).
> The arguments are just passed through .execute(), which doesn't really
> care one way or the other.
> 
> 	Tediously, .execute() calls ._execute(), which has:
> ...
>         try:
>             if args is None:
>                 r = self._query(query)
>             else:
>                 r = self._query(query % self.connection.literal(args))
>         except TypeError, m:
> ...
> 
> 	Since .literal() accepts single objects (well, in truth, I'd
> guess one would have to say that it is .escape() that processes the
> arguments -- I can't say what that does, as it is likely in the binary
> module. However, the actual forming of the final query string /is/ the
> standard Python "string" % arg operator, which, in my experience, has
> never complained about not being given a 1-tuple.
>  
True. I had hopes that this might explain another riddle I couldn't 
solve: datefield is a database column of type date, and I execute two 
queries:

a) SELECT * FROM mytable WHERE datefield = %s

b) SELECT * FROM mytable WHERE datefield IN (%s, %s)

case a): the parameter for %s can be a mx.DateTime object, a 
datetime.date object or the sort of DateTime object MySQLdb returns from 
another query; or it can be a string with format 'YYYY-MM-DD'. The 
results of the query are correct in every case.

case b): the parameters must be strings of the form 'YYYY-MM-DD'. With 
all other sorts of parameters (DateTime objects, strings in other date 
formats) the query doesn't find anything.

I tried this with different versions of MySQL, MySQLdb and Python, under 
Windows and Linux, always with the same results.

Now I've looked at conn.literal(args) for a pair of DateTime objects and 
for a single one:

 >>> arg
<DateTime object for '2004-06-18 00:00:00.00' at 1199da0>
 >>> arglist
[<DateTime object for '2004-07-29 00:00:00.00' at 117af20>, <DateTime 
object for '2004-07-07 00:00:00.00' at 1199de0>]
 >>> conn.literal(arglist)
("'2004-07-29 00:00:00'", "'2004-07-07 00:00:00'")
 >>> conn.literal(arg)
"'2004-06-18 00:00:00'"
 >>> s1 = 'SELECT * FROM fehllief WHERE fehltag IN (%s, %s)'
 >>> s1 % conn.literal(arglist)
"SELECT * FROM fehllief WHERE fehltag IN ('2004-07-29 00:00:00', 
'2004-07-07 00:00:00')"
 >>> s2 = 'SELECT * FROM fehllief WHERE fehltag = %s'
 >>> s2 % conn.literal(arg)
"SELECT * FROM fehllief WHERE fehltag = '2004-06-18 00:00:00'"
 >>> curs.execute(s1, arglist)
0L
 >>> curs.execute(s2, arg)
1L

Why doesn't the query using IN find anything while the query using = 
does? The records are there, of course.

Koczian



More information about the Python-list mailing list