天天看點

django2.2+mysql遇到的坑

可能是由于Django使用的MySQLdb庫對Python3不支援,我們用采用了PyMySQL庫來代替,導緻出現各種坑

第一個坑:

無論你是否執行pip install mysqlclient安裝的最新版的,都抛出:

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

解決:

第一種方法:

django降到2.1.4版本就OK了

第二種方法:

找到Python安裝路徑下的base.py檔案

我ubuntu上路徑是 /usr/local/lib/python3.5/dist-packages/django/db/backends/mysql/base.py

将檔案中如下代碼注釋:(可能需先關閉pycharm IDE)

if version < (1, 3, 7):

    raise ImproperlyConfigured('mysqlclient 1.3.7 or newer is required; you have %s.' % Database.__version__)

第二個坑:

py3預設str是unicode編碼,通過encode方法編碼成bytes類型,後者才有decode解碼方法。

提示錯誤來源:

Python36\lib\site-packages\django\db\backends\mysql\operations.py", line 149, in last_executed_query
  • 這裡網上一搜一堆的把encode改成decode方法,我靠,這誰的腦洞無敵了

源方法内容(pip安裝的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結果,内容為

SELECT @@SQL_AUTO_IS_NULL

資料類型為str
           
  • 這裡網上還有注釋大法,LZ不知道注釋了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轉換成str了

我靠!!!這尼瑪官網2.2.1/2.2.2(目前最新版)的包不是害人麼,記得該檔案上面引入下這個方法

from django.utils.encoding import force_str
           

然後再執行managa.py指令,可以了