I try to use django1.5 and pymysql as MySQLdb as here How to make Django work with unsupported MySQL drivers such as gevent-mysql or Concurrence's MySQL driver?
In the top of my management command:
+try:
+ import pymysql
+ pymysql.install_as_MySQLdb()
+except ImportError:
+ pass
but get error:
/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
how to fix it?
In MySQLdb
, the Thing2Literal
method is not used if you're using a recent enough version of MySQL, in which case the connection's string_literal
method is used instead when a connection is available.
You'll need to patch pymysql
so that it does the same thing and lets you use the connection's method.
This method is used for escaping SQL statements. PLaying around with it consequently has security issues that you must consider.
The reason why you want to use the connection's method is the charset, which plays a role in escaping.
ImportError
This is a pretty easy one, you just need to implement a dummy Thing2Literal
method in pymysql.converters
. We'll never call it anway, so we don't care about it:
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
at runtime when an connection is availableIn pymysql.connections.Connection
, add: import pymysql.converters
At the end of pymysql.connections.Connection.__init__
, add the following:
pymysql.converters.Thing2Literal = lambda o, d: self.escape(o)
And at the end of pymysql.connections.Connection.__del__
, add the reverse:
pymysql.converters.Thing2Literal = pymysql.converters._Thing2Literal
We can discard the d
argument because it's a dictionary of existing conversions, which are already available to the Connection.escape
method.
There's a good chance this will break, and expose security issues.
Additionally, I'm pretty sure it will break badly if you have several active connections that use different charsets.
You might need to play around a bit with Django too to make sure it uses your monkey-patched version when available - namely replace from MySQLdb.converters import Thing2Literal
with something that still binds the Thing2Literal
name to the module.
You can of course achieve the same effect without patching django and making the _Thing2Literal
function smarter.
Just ran into same issue on Django 1.5.1 and PyMySQL 0.5
Fixed by using CMGS fork (https://github.com/CMGS/PyMySQL) of PyMySQL. Hopefully this will make it's way into mainline PyMySQL. See CMGS's pull request here: https://github.com/petehunt/PyMySQL/pull/106
Judging from author's comments and the feedback in the pull request, I think it's pretty solid for production use.
Example requirements.txt line: -e git://github.com/CMGS/PyMySQL.git#egg=PyMySQL-dev
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With