我尝试将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
如何解决?
答案 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
功能更智能的情况下实现相同的效果。