django 1.5 + pymysql错误:ImportError:无法导入名称Thing2Literal

时间:2013-03-09 18:39:50

标签: python django python-2.7 pymysql

我尝试将django1.5和pymysql用作MySQLdb,如How to make Django work with unsupported MySQL drivers such as gevent-mysql or Concurrence's MySQL driver?

在我的管理命令的顶部:

+try:
+    import pymysql
+    pymysql.install_as_MySQLdb()
+except ImportError:
+    pass 

但得到错误:

/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 30, in <module>
    from MySQLdb.converters import conversions, Thing2Literal
ImportError: cannot import name Thing2Literal

如何解决?

2 个答案:

答案 0 :(得分:3)

刚刚在Django 1.5.1和PyMySQL 0.5

上遇到了同样的问题

使用PyMySQL的CMGS fork(https://github.com/CMGS/PyMySQL)修复。希望这将使它成为主线PyMySQL的方式。请在此处查看CMGS的拉取请求:https://github.com/petehunt/PyMySQL/pull/106

根据作者的评论和拉取请求中的反馈来判断,我认为它对于生产使用非常可靠。

示例要求.txt行: -e git://github.com/CMGS/PyMySQL.git#egg=PyMySQL-dev

答案 1 :(得分:2)

MySQLdb中,如果您使用的是最新版本的MySQL,则不使用Thing2Literal方法,在这种情况下,当连接是连接时,使用连接的string_literal方法可用。

您需要修补pymysql以便它执行相同的操作并允许您使用连接的方法。

上下文

此方法用于转义SQL语句。因此,播放它有安全问题,你必须考虑。

你想要使用连接方法的原因是charset,它在转义中起作用。

修复ImportError

这很简单,您只需要在pymysql.converters中实现虚拟Thing2Literal方法。我们永远不会称之为,所以我们不关心它:

def _Thing2Literal(o,d):
    """
    Implemented for compatibility with Django.
    This function is overriden by the connection's escape method when one is available.
    """
    raise NotImplementedError('Thing2Literal is only implemented through the Connection object.')

 Thing2Literal = _Thing2Literal

在连接可用时在运行时修补Thing2Literal

pymysql.connections.Connection中,添加:import pymysql.converters

pymysql.connections.Connection.__init__结束时,添加以下内容:

pymysql.converters.Thing2Literal = lambda o, d: self.escape(o)

pymysql.connections.Connection.__del__结束时,添加反向:

pymysql.converters.Thing2Literal = pymysql.converters._Thing2Literal

我们可以放弃d参数,因为它是现有转化的字典,已经可用于Connection.escape方法。

注意事项

这很有可能会破坏,并暴露出安全问题 另外,如果你有几个使用不同字符集的活动连接,我很确定它会破坏。


您可能还需要使用Django来确保它在可用时使用您的猴子修补版本 - 即将from MySQLdb.converters import Thing2Literal替换为仍然将Thing2Literal名称绑定到模块的内容。

当然,您可以在不修补django并使_Thing2Literal功能更智能的情况下实现相同的效果。