Django2.2使用mysql数据库pymysql版本不匹配问题的解决过程与总结
前置条件
django版本:2.2.1
python版本:3.6.6
mysql版本:mysql-community8.0.15
问题
在搭建django项目,配置mysql数据库时遇到无法迁移数据库的问题,错误信息如下图:
问题分析过程
由错误信息,可大致看出是一个叫mysqlclient的包版本不匹配导致的问题。
搜索引擎检索相关错误,得知:python访问mysql需要安装对应的驱动包,即将mysql的api接口转换成python格式供数据库应用软件开发者直接调用的第三方库。django2.2默认使用“mysqlclient”这个库去连接mysql,而网上很多教程中使用的是“pymysql”。这两个库有什么区别呢?继续搜索。
pymysql、mysqlclient与mysqldb
pypi中关于pymsql的说明:最新版本0.9.3,用纯python语言开发的mysql驱动库,大部分api与mysqlclient和mysqldb兼容,python2只支持2.7版本,python3版本支持3.4及以上版本,mysql版本要求5.5版本及以上。
pypi中关于mysqlclient的说明:最新版本1.4.2,是mysqldb1的分支,支持python3。
pypi中关于mysqldb的说明:包名称为mysql-python,mysql数据库的接口库,支持mysql数据库3.23-5.5版本,支持python2.4-2.7版本,线程安全。
此时,错误信息中的两个版本号就可以解释了,因为我按网上教程,在django配置文件settings.py中使用了pymsql来连接mysql数据库,这是报错的原因。为什么错误信息中提示我的myclient版本是0.9.3?猜想(没有验证)是因为“pymysql.install_as_mysqldb()”这行代码,因为django而默认使用mysqldb(或myclient,一个东西,可看成python2和python3的对应版本),而pymysql是一个很方便的支持python3的mysql数据库驱动库,所以把它以mysqldb的名字安装,此时django把pymsql的版本号当成myclient的版本号输出。
到这里,问题解决的思路就比较明确了,两种方式:一种是修改django的源码,让版本号通过校验;另一种是安装合适的myclient版本。
在选择解决方案之前,心中有个疑惑还没有解决:pymysql和myclient都提供mysql数据库的python版api,用哪个好?继续搜索引擎大法。
一通对比搜索后,找到下面三篇看上去比较严谨可信的文章:
https://blog.csdn.net/u011510825/article/details/86632598
https://my.oschina.net/sukai/blog/1930092
https://blog.csdn.net/sigmarising/article/details/83473039
总结起来就是:mysqldb(mysqlclient)c语言开发,速度相比pymysql优势明显;pymysql由于纯python开发,与python无缝对接,使用、安装方便,反而用的人更多;mysqlclient对mysql8的默认用户加密方式 caching_sha2_password不支持(未验证)
经过一翻对比,决定使用mysqlclient,一是考虑其性能更好,二是不想随意修改django源码。
mysqlclient安装
果不其然,mysqlclient的安装并不顺利,使用pip指令安装直接报错,错误信息如图:
继续搜索,查到是因为mysql-devel没安装,顺便检索到mysql-devel的作用:header files, debug symbols. required when building source packages that requires them,里面包含了c语言的一些头文件,想要编译安装mysql的其它客户端程序时,需要用到这个库。
centos系统下输入rpm查找指令:rpm -qa|grep mysql查看mysql安装信息,发现确实没有安装mysql-devel,于是下载与已安装的mysql服务相同版本号(不同版本可能又会引出其它问题)的mysql-devel库的rpm包,安装成功后再次使用pip命令安装myclient库,成功。
修改django全局配置文件settings.py,取消导入pymysql库,注释代码pymysql.install_as_mysqldb(),再次迁移数据库,成功。
总结
以上是在学习django过程中遇到的一个小问题,从一个小问题一层层深入、分析问题的原因,从问题中引出新的问题,层层递进,可以由一点串成一条线甚至到一张网(如果时间允许的话)。问题本身意义不大,但自觉在解决这个问题的过程中层层递进,由点到线的学习思想很有总结意义,特记录于此,也可供更多人学习、参考。