Django2.2使用mysql資料庫pymysql版本不匹配問題的解決過程與總結

漫漫蕪發表於2019-05-24

前置條件

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過程中遇到的一個小問題,從一個小問題一層層深入、分析問題的原因,從問題中引出新的問題,層層遞進,可以由一點串成一條線甚至到一張網(如果時間允許的話)。問題本身意義不大,但自覺在解決這個問題的過程中層層遞進,由點到線的學習思想很有總結意義,特記錄於此,也可供更多人學習、參考。

相關文章