You can't pass a tuple as a parameter to execute(). There's
no database adapter that this would work on. This is one of
the rare cases where you have to build up your query with
the % operator, i.e.
c.execute("""SELECT * FROM localekit_attributes
WHERE attribute IN %s""" % ((1, 2), ))
A tuple is effectively a multi-valued argument, and only
single-valued arguments can be passed to execute().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is from the log:
051012 14:21:04 3 Query SELECT * FROM
localekit_attributes WHERE attribute IN ('About', 'Cancel')
051012 14:22:05 3 Query SELECT * FROM
localekit_attributes WHERE attribute IN ('About',)
In both cases I'm passing a tuple in as an argument - so it
works all but for the special case of the one element tuple
which raises a 1064 syntax error because of the extra comma.
Unfortunately your suggestion of using %s formatting
generates the same syntax error!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've written some code on-the-fly to try to demonstrate how
to fix/work around this:
Python 2.4.2 (#1, Oct 3 2005, 09:43:02) [GCC 3.4.4 (Gentoo 3.4.4-r1, ssp-3.4.4-1.0, pie-8.7.8)] on
linux2
Type "help", "copyright", "credits" or "license" for more
information.
Hi Andy, I've encountered this bug too... nice solution
here, I adapted it just a bit so that it works on the
current version of your library and can provide a patch if
you want. can we expect to find it in the distributed module?
/home/mariof/Local/mysql-python.sourceforge.net/MySQLdb/MySQLdb/cursors.py
2006-11-10 15:03:39.000000000 +0100
+++
/home/mariof/lib/python2.4/site-packages/MySQLdb/cursors.py
2006-11-10 16:02:07.000000000 +0100
@@ -121,7 +121,8 @@
if args is None:
r = self._query(query)
else:
- r = self._query(query %
self.connection.literal(args))
+ r = self._query(query %
tuple([self.connection.literal(item)
+ for item in
args]))
except TypeError, m:
if m.args[0] in ("not enough arguments for
format string",
"not all arguments converted"):
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Logged In: YES
user_id=71372
You can't pass a tuple as a parameter to execute(). There's
no database adapter that this would work on. This is one of
the rare cases where you have to build up your query with
the % operator, i.e.
c.execute("""SELECT * FROM localekit_attributes
WHERE attribute IN %s""" % ((1, 2), ))
A tuple is effectively a multi-valued argument, and only
single-valued arguments can be passed to execute().
Logged In: NO
So I have to do the quoting myself?
As I said tuples with more than one element are quoting
correctly which makes this a very useful function.
Logged In: YES
user_id=71372
Well I guess it depends on what your error is, but since you
never said what that is, I'm not going to guess.
Logged In: NO
This is from the log:
051012 14:21:04 3 Query SELECT * FROM
localekit_attributes WHERE attribute IN ('About', 'Cancel')
051012 14:22:05 3 Query SELECT * FROM
localekit_attributes WHERE attribute IN ('About',)
In both cases I'm passing a tuple in as an argument - so it
works all but for the special case of the one element tuple
which raises a 1064 syntax error because of the extra comma.
Unfortunately your suggestion of using %s formatting
generates the same syntax error!
Logged In: YES
user_id=71372
I've written some code on-the-fly to try to demonstrate how
to fix/work around this:
Python 2.4.2 (#1, Oct 3 2005, 09:43:02)
[GCC 3.4.4 (Gentoo 3.4.4-r1, ssp-3.4.4-1.0, pie-8.7.8)] on
linux2
Type "help", "copyright", "credits" or "license" for more
information.
To actually use this, you'll need to do:
converters[tuple] = escape_tuple
(For older versions of Python, use types.TupleType instead
of tuple)
If you look at conversions.py, you should see where this is
being done with escape_sequence already.
Logged In: YES
user_id=71372
Here's another variation:
def quote_tuple(t, d):
return "(%s)" % ','.join([item for item in
escape_sequence(t,d)])
This is not quite perfect (it fails for nested tuples), but
it may be better than the original solution.
Logged In: YES
user_id=71372
Actually, this seems to work perfectly well on nested tuples
as well:
Same function should work for lists as well.
I'll probably incorporate this.
Logged In: NO
Thanks for this code and the explanation. Certainly neater
than the workaround I've come up with!
Charlie
Logged In: YES
user_id=1079993
Do you (and when) plan to fix this issue?
Logged In: YES
user_id=512199
Hi Andy, I've encountered this bug too... nice solution
here, I adapted it just a bit so that it works on the
current version of your library and can provide a patch if
you want. can we expect to find it in the distributed module?
thanks, Mario.
diff -U3
/home/mariof/Local/mysql-python.sourceforge.net/MySQLdb/MySQLdb/converters.py
/home/mariof/lib/python2.4/site-packages/MySQLdb/converters.py
/home/mariof/Local/mysql-python.sourceforge.net/MySQLdb/MySQLdb/converters.py
2006-11-10 15:11:37.000000000 +0100
+++
/home/mariof/lib/python2.4/site-packages/MySQLdb/converters.py
2006-11-10 16:04:07.000000000 +0100
@@ -107,13 +107,16 @@
def array2Str(o, d):
return Thing2Literal(o.tostring(), d)
+def quote_tuple(t, d):
+ return "(%s)" % (','.join(escape_sequence(t,d)))
+
conversions = {
types.IntType: Thing2Str,
types.LongType: Long2Int,
types.FloatType: Float2Str,
types.NoneType: None2NULL,
- types.TupleType: escape_sequence,
- types.ListType: escape_sequence,
+ types.TupleType: quote_tuple,
+ types.ListType: quote_tuple,
types.DictType: escape_dict,
types.InstanceType: Instance2Str,
array.ArrayType: array2Str,
diff -U3
/home/mariof/Local/mysql-python.sourceforge.net/MySQLdb/MySQLdb/cursors.py
/home/mariof/lib/python2.4/site-packages/MySQLdb/cursors.py
/home/mariof/Local/mysql-python.sourceforge.net/MySQLdb/MySQLdb/cursors.py
2006-11-10 15:03:39.000000000 +0100
+++
/home/mariof/lib/python2.4/site-packages/MySQLdb/cursors.py
2006-11-10 16:02:07.000000000 +0100
@@ -121,7 +121,8 @@
if args is None:
r = self._query(query)
else:
- r = self._query(query %
self.connection.literal(args))
+ r = self._query(query %
tuple([self.connection.literal(item)
+ for item in
args]))
except TypeError, m:
if m.args[0] in ("not enough arguments for
format string",
"not all arguments converted"):