宣告:以下內容均為我個人的理解,如果發現錯誤或者疑問可以聯絡我共同探討
簡介
在Django中使用mysql資料庫是很常見的,但是升級到Django2.0以後,已經不支援Python2.x,mysql的配置也需要隨之改變
配置
配置settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname',
'USER': 'dbuser',
'PASSWORD': 'dbpassword',
'HOST':'dbhost',
'PORT':'dbport'
}
}
使用pymysql
由於安裝mysqlclient不支援python3,所以使用pymysql包,安裝pymysql並匯入
pip install pymysql
配置pymysql,在settings.py所在的目錄下的__init__.py檔案中匯入
import pymysql
pymysql.install_as_MySQLdb()
修改原始碼中的問題
由於在python3中不在使用mysqlclient,所以原始碼中限制mysqlclient版本這一程式碼就不適用於現在的環境
檔案路徑
django\db\backends\mysql\base.py
,將版本限制異常給註釋掉在檔案的第35-36行# if version < (1, 3, 13): # raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
由於python2的str是位元組流(類似於bytes型別)需要通過decode轉換成unicode型別才能使用,但在python3中str預設unicode型別不需要轉換且沒有decode解碼所以要將這裡的程式碼修改。在最新的Django原始碼中已經將這裡修改了(可以通過Django官網或github檢視),在最新的原始碼中使用django.utils.encoding中force_str方法解決了該問題,force_str方法實際上是force_text方法,force_text方法通過判斷傳入引數的型別後將型別轉為unicode型別的str之後返回
\django\utils\encoding.py ······ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'): """ Similar to smart_text, except that lazy instances are resolved to strings, rather than kept as lazy objects. If strings_only is True, don't convert (some) non-string-like objects. """ # Handle the common case first for performance reasons. if issubclass(type(s), str): return s if strings_only and is_protected_type(s): return s try: if isinstance(s, bytes): s = str(s, encoding, errors) else: s = str(s) except UnicodeDecodeError as e: raise DjangoUnicodeDecodeError(s, *e.args) return s
最後修改\django\db\backends\mysql\operations.py檔案中的last_executed_query方法(記得匯入force_str)
from django.utils.encoding import force_str ··· 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')
本作品採用《CC 協議》,轉載必須註明作者和本文連結