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?
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
In
MySQLdb
, theThing2Literal
method is not used if you're using a recent enough version of MySQL, in which case the connection'sstring_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.Context
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.
Fix the
ImportError
This is a pretty easy one, you just need to implement a dummy
Thing2Literal
method inpymysql.converters
. We'll never call it anway, so we don't care about it:Monkey-patching
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:And at the end of
pymysql.connections.Connection.__del__
, add the reverse:We can discard the
d
argument because it's a dictionary of existing conversions, which are already available to theConnection.escape
method.Caveats
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 theThing2Literal
name to the module.You can of course achieve the same effect without patching django and making the
_Thing2Literal
function smarter.