MySQLdb execute()适用于unicode,但不适用于unicode的子类

时间:2016-10-29 10:06:13

标签: python django unicode mysql-python

我正在构建一个使用其他方法扩展unicode类的库,我发现MySQLdb在使用我的unicode类时失败了。

这有效:

In [23]: c.execute("""SELECT * FROM django_site WHERE domain LIKE %s""",(u'éric',))
Out[23]: 0L

但这不是:

In [24]: class UnicodeExtended(unicode):
    ...:     pass
    ...: 

In [25]: c.execute("""SELECT * FROM django_site WHERE domain LIKE %s""",(UnicodeExtended(u'éric'),))
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-25-9145669d2b00> in <module>()
----> 1 c.execute("""SELECT * FROM django_site WHERE domain LIKE %s""",(UnicodeExtended(u'éric'),))

/usr/lib/python2.7/dist-packages/MySQLdb/cursors.pyc in execute(self, query, args)
    205                 args = dict((key, db.literal(item)) for key, item in args.items())
    206             else:
--> 207                 args = tuple(map(db.literal, args))
    208             if not PY2 and isinstance(query, bytes):
    209                 query = query.decode(db.unicode_literal.charset)

/usr/lib/python2.7/dist-packages/MySQLdb/connections.pyc in literal(self, o)
    302 
    303         """
--> 304         s = self.escape(o, self.encoders)
    305         # Python 3 doesn't support % operation for bytes object.
    306         # We should decode it before using %.

/usr/lib/python2.7/dist-packages/MySQLdb/connections.pyc in string_literal(obj, dummy)
    213             # Note: string_literal() is called for bytes object on Python 3.
    214             def string_literal(obj, dummy=None):
--> 215                 return db.string_literal(obj)
    216             return string_literal
    217 

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)

是否可以以任何方式将unicode子类用于sql查询参数?

可能是我的UnicodeExtended类中缺少某些东西......有什么想法吗?

我正在使用Python 2.7和MySQLdb 1.3.7

1 个答案:

答案 0 :(得分:0)

我发现MySQLdb直接测试UnicodeType,它不支持unicode子类化。默认情况下,MySQLdb将对无法识别的对象类型执行str()。所以诀窍是添加__str_方法:

class UnicodeExtended(unicode):
    def __str__(self):
        return self.encode('utf-8')

这很有效。当使用UnicodeExtended对象时,这也避免了django的“_last_executed”错误。