Conversions turns list into 'pseudo-tuple'
wryun opened this issue · comments
In converters.py, there are rules to take ListTypes and TupleTypes to MySQL literals (which are used when you pass a list as a parameter).
Unfortunately, the code that does this (escape_sequence) uses a Python tuple to produce the string for MySQL insertion, which is a bad idea when you have a single element list (producing things like ('1',) - i.e. invalid SQL). I'm worried that I'm not understanding the intent of this code properly, though, since the action for a DictType appears to be completely insane (at least in the cursor.execute context). Should I only be using 'sets' (where the appropriate join is run)?
Currently I'm working around this as follows:
def fixed_escape_sequence(o, d):
if len(o) == 1:
return '(%s)' % MySQLdb.converters.escape(o[0], d)
else:
return MySQLdb.converters.escape_sequence(o, d)
from copy import copy
conversions = copy(MySQLdb.converters.conversions)
conversions[types.ListType] = fixed_escape_sequence
conversions[types.TupleType] = fixed_escape_sequence
But it would be nicer if escape_sequence was fixed in the C code.
Ok, having thought about this, I assume the intent is to take a single list as a parameter and have it by processed by Python's internal formatting. I'm guessing this is something that will be changed in moist.
To clarify my somewhat opaque earlier remark now that I understand this more (and this is referenced elsewhere): MySQLdb's db.literal function is strangely overloaded so that it tries to deal with both the initial list/dict argument in the execute (i.e. all the parameters) and the content inside the parameters. That is, list/dict conversions are intended to process the parameters, whereas all other converters do the actual escaping for MySQL.
This has the unfortunate effect that it 'almost' supports lists/tuples for escaping (but not quite). I assume the almost support is a bug - it should just fail - so I'll reopen this, since I think people need to know. Though I understand fixing would require significant reworking.
PS This is why people get the db to parameterise, folks...
Just saw #36 . Excellent!