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

Evg*_*Evg 5 python django python-2.7 pymysql

我尝试用django1.5和pymysql这里这样MySQLdb的如何让Django的不支持的MySQL驱动如GEVENT-MySQL或请求权竞合的MySQL驱动程序工作?

在我的管理命令的顶部:

+try:
+    import pymysql
+    pymysql.install_as_MySQLdb()
+except ImportError:
+    pass 
Run Code Online (Sandbox Code Playgroud)

但得到错误:

/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
Run Code Online (Sandbox Code Playgroud)

怎么解决?

Tho*_*zco 2

在 中MySQLdbThing2Literal如果您使用的是足够新的 MySQL 版本,则不会使用该方法,在这种情况下,string_literal当连接可用时,将使用连接的方法。

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

语境

该方法用于转义SQL语句。因此,使用它会带来您必须考虑的安全问题。

之所以要使用连接的方法,是因为字符集,它起到了转义的作用。

修复ImportError

这是一个非常简单的方法,您只需要Thing2Literalpymysql.converters. 我们永远不会调用它,所以我们不关心它:

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
Run Code Online (Sandbox Code Playgroud)

Thing2Literal当连接可用时在运行时进行猴子修补

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

在 的末尾pymysql.connections.Connection.__init__添加以下内容:

pymysql.converters.Thing2Literal = lambda o, d: self.escape(o)
Run Code Online (Sandbox Code Playgroud)

在 的末尾pymysql.connections.Connection.__del__添加相反的内容:

pymysql.converters.Thing2Literal = pymysql.converters._Thing2Literal
Run Code Online (Sandbox Code Playgroud)

我们可以丢弃该d参数,因为它是现有转换的字典,该字典已经可供该Connection.escape方法使用。

注意事项

这很有可能会崩溃并暴露安全问题。
此外,我很确定如果您有多个使用不同字符集的活动连接,它会严重损坏。


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

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