5

我尝试使用 django1.5 和pymysql作为 MySQLdb 在这里如何使 Django 使用不受支持的 MySQL 驱动程序,例如 gevent-mysql 或 Concurrence 的 MySQL 驱动程序?

在我的管理命令的顶部:

+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

如何解决?

4

2 回答 2

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

从作者的评论和 pull request 中的反馈来看,我认为它非常适合生产使用。

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

于 2013-05-24T22:12:53.123 回答
2

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

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

语境

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

之所以要使用connection的方法,是因为charset,起到转义的作用。

修复ImportError

这是一个非常简单的Thing2Literal方法,您只需要在pymysql.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

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功能更智能的情况下达到同样的效果。

于 2013-03-09T20:28:21.617 回答