在使用Django框架開發web應用的過程當中,不可避免的會涉及到數據的管理(增、刪、改、查),而一旦談到數據的管路操做,就須要使用數據管理的軟件。例如:mysql, oracle等python
通常的對數據進行操做時候,以往都是經過原生的SQL語句,而後使用pymysql模塊遠程操做mysql。mysql
可是這樣的操做會存在兩方面的問題,git
一、sql語句的執行效率:應用開發程序員須要耗費一大部分經歷去優化SQL語句程序員
二、一旦涉及到遷庫,針對mysql開發的sql語句沒法直接應用到oracle數據庫上web
爲了解決上述問題,Django引入了ORM(object relational Mapping)即對象關係映射,是在pymysql之上又進行了一層封裝,對於數據庫的操做,不須要在編寫原生的sql,取而代之的是基於面相對象的思想去編寫類、對象、調用相應的方法等,sql
ORM會將其轉換/映射成原生SQL而後交給pymysql執行 如圖:數據庫
具體步驟以下:django
一、建立Django 項目 新建名app01,在app01的models.py中建立模型bootstrap
1 from django.db import models 2 3 4 # Create your models here. 5 6 class Employee(models.Model): 7 name = models.CharField(max_length=20) 8 gender = models.BooleanField(default=1) 9 birth = models.DateField() 10 department = models.CharField(max_length=30) 11 salary = models.DecimalField(max_digits=10, decimal_places=1)
django的orm支持多種數據庫,若是想將上述的模型轉爲mysql數據庫中的表,須要在settings中進行設置python3.x
1 # DATABASES = { 2 # 'default': { 3 # 'ENGINE': 'django.db.backends.sqlite3', 4 # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 5 # } 6 # } 7 8 #須要將原有的(上面)DATABASES註釋掉改爲本身的(下面) 9 DATABASES = { 10 'default': { 11 'ENGINE': 'django.db.backends.mysql',#使用Mysql數據庫 12 'NAME': 'tb',#須要鏈接的數據庫 13 'USER': 'root', #鏈接的數據庫用戶名 14 'PASSWORD': 'sipg09827', #鏈接的數據庫密碼 15 'HOST': '', #mysql服務監聽的ip 16 'PORT': '3306', #mysql服務監聽的端口(通常默認爲3306) 17 'ATOMIC_REQUEST': True, 18 } 19 }
三、其實python解釋器在運行django程序時,django的orm底層操做數據庫的python模塊默認是mysqldb而非pymysql,而後對於解釋器而言,Python2.X解釋器支持的操做數據庫的模塊是mysqldb,而Python3.X解釋器支持的操做數據庫模塊是Pymysql,
若是使用python3.x,須要修改django的orm默認操做數據庫的模塊爲pymysql,具體作法以下:
四、若是想打印orm轉換過程當中的原生sql,須要在settings中進行配置日誌
1 LOGGING={ 2 'version': 1, 3 'disable_existing_loggers': False, 4 'handle': { 5 'level': 'DEBUG', 6 'class': 'logging.StreamHandler' 7 }, 8 'loggers': { 9 'django.db.backends' :{ 10 'handlers':['console'], 11 'propagate':True, 12 'level':'DEBUG' 13 } 14 } 15 }
最後在命令行中執行兩條數據庫遷移命令,既可在指定的數據庫中建立表:
>>>python manage.py makemigrations
>>>python manage.py migrate
#注意: #一、makemigations 只是生成一個數據庫遷移記錄的文件,而migrate纔是將更改真正提交到數據庫執行 #二、數據庫遷移記錄的文件存放於app01下的migrations文件裏
注意 在命令行執行 python manage.py migrate
進行數據遷移時報以下錯誤:
...... File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 36, in <module> raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__) django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
根據最後兩行的提示,mysqlclient 版本不夠新,可是我已經都安裝的最新版本了呀
問題緣由
執行命令時,仔細看下報錯的倒數第三行,已經告訴你是在 base.py (能夠按住Ctrl而後點擊鼠標連接進去)第 36 行報的錯,根據你的提示路徑打開 base.py,把 3五、36 行前面加 # 註釋掉就行了,就像下面這樣:
34 version = Database.version_info 35 #if version < (1, 3, 13): 36 # raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__) 37
如今再次執行命令,上面的報錯已經沒有了,可是又有了新的錯誤,看下面怎麼解決
AttributeError: 'str' object has no attribute 'decode'
解決了上面的問題後,又遇到下面這個錯誤:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/db/backends/mysql/operations.py", line 146, in last_executed_query query = query.decode(errors='replace') AttributeError: 'str' object has no attribute 'decode'
提示屬性錯誤:「str」對象沒有屬性「decode」。
問題的緣由是,在 Python3 裏:
這個估計是 django 的 bug 了。
解決方法:
operations.py
1 140 def last_executed_query(self, cursor, sql, params): 2 141 # With MySQLdb, cursor objects have an (undocumented) "_executed" 3 142 # attribute where the exact query sent to the database is saved. 4 143 # See MySQLdb/cursors.py in the source distribution. 5 144 query = getattr(cursor, '_executed', None) 6 145 if query is not None: 7 146 query = query.encode(errors='replace') # 這裏把 decode 改成 encode 8 147 return query
此時,再次執行命令就不報錯了,大功告成!