【问题标题】:django 1.5 + pymysql error: ImportError: cannot import name Thing2Literaldjango 1.5 + pymysql 错误:ImportError: cannot import name Thing2Literal
【发布时间】:2013-02-25 04:56:35
【问题描述】:

我尝试使用 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

如何解决?

【问题讨论】:

  • 看起来pymysql 并没有实现MySQLdb 提供的所有东西(并且Django 1.5 需要存在),所以我认为你只是不走运。 stackoverflow.com/a/7166730/893780下面的评论也提到了你的问题。

标签: python django python-2.7 pymysql


【解决方案1】:

刚刚在 Django 1.5.1 和 PyMySQL 0.5 上遇到了同样的问题

已通过使用 PyMySQL 的 CMGS fork (https://github.com/CMGS/PyMySQL) 修复。希望这将使其进入主线 PyMySQL。在此处查看 CMGS 的拉取请求:https://github.com/petehunt/PyMySQL/pull/106

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

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

【讨论】:

    【解决方案2】:

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

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

    上下文

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

    之所以要使用connection的方法,是因为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 函数更智能的情况下达到同样的效果。

    【讨论】:

      猜你喜欢
      • 2012-12-15
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 2013-06-05
      • 2019-10-24
      相关资源
      最近更新 更多