在使用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
此时,再次执行命令就不报错了,大功告成!