Django 2.2 使用 PyMySQL 时的常见报错与修复方案

南乔
南乔
发布时间:2026-10-13 | 4人浏览过
原创

本文详解Django 2.2在Python 3环境下使用PyMySQL替代mysqlclient时遇到的两个典型错误:一是版本校验失败导致的ImproperlyConfigured异常,二是字符串类型缺少decode方法引发的TypeError。通过修改Django源码或引入force_str函数,可有效解决这些兼容性问题,确保项目正常运行。

Django 2.2 使用 PyMySQL 时的常见报错与修复方案

由于Django默认的MySQLdb库不支持Python 3,开发者通常采用PyMySQL库进行替代,但这往往会导致一系列兼容性问题。特别是在执行以下两条命令时,容易遇到阻碍:

执行迁移或 inspectdb 命令


python manage.py makemigrations
or
python manage.py inspectdb

错误一:mysqlclient 版本过低报错

第一个坑(提示你的mysqlclient版本过低)

无论你是否通过pip install mysqlclient安装了最新版,系统均会抛出如下错误:


django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

遇到此类报错确实令人沮丧,此时可尝试参考网络上的解决方案,即采用注释相关代码的方式来解决。

定位到Python安装路径下的Python36-32\Lib\site-packages\django\db\backends\mysql\base.py文件。

对该文件中的特定代码段进行注释(操作前建议先关闭PyCharm IDE以避免文件占用)。


if version < (1, 3, 3):
  raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

错误二:str 类型缺少 decode 方法

第二个坑(str类型没有decode方法)

在Python 3中,str类型默认即为unicode编码,需通过encode方法转换为bytes类型后,bytes对象才具备decode解码方法。报错来源指向:Python36\lib\site-packages\django\db\backends\mysql\operations.py,第149行的last_executed_query函数。

网络上常见的解决方案是将encode改为decode,但这种做法逻辑混乱。以下是Django 2.2.1原版中该方法的实际内容:


  def last_executed_query(self, cursor, sql, params):
    # With MySQLdb, cursor objects have an (undocumented) "_executed"
    # attribute where the exact query sent to the database is saved.
    # See MySQLdb/cursors.py in the source distribution.
    query = getattr(cursor, '_executed', None)
    if query is not None:
      query = query.decode(errors='replace')
    return query

通过print语句输出query结果,其数据类型显示为str。


SELECT @@SQL_AUTO_IS_NULL

数据类型为str

网上还有建议直接注释if判断语句的“注释大法”,但由于不确定注释后是否会产生其他副作用,此处不予采纳。

随后查阅Django GitHub仓库中该文件最新及历史版本,发现master分支的内容已更新如下:


  def last_executed_query(self, cursor, sql, params):
    # With MySQLdb, cursor objects have an (undocumented) "_executed"
    # attribute where the exact query sent to the database is saved.
    # See MySQLdb/cursors.py in the source distribution.
    # MySQLdb returns string, PyMySQL bytes.
    return force_str(getattr(cursor, '_executed', None), errors='replace')

观察函数名可知,其目的是强制将SQL查询结果转换为字符串类型。

解决方案:引入 force_str 函数

值得注意的是,Django官网发布的2.2.1/2.2.2版本(当时最新版)并未包含此修复,这可能导致用户困惑。因此,需要在该文件上方引入相关方法。


from django.utils.encoding import force_str

完成上述修改后,再次执行manage.py命令,问题即可解决。

以上内容为本文的全部总结,希望能为读者的学习提供有益帮助,同时也欢迎大家继续支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表