[Django] Django 连接 MySQL数据库 以及 makemigrations&migrate 过程详解总结
Django 连接 MySQL数据库过程
安装MySQL数据库
Django自带的是SQLite数据库的, 如果要使用MySQL数据库, 则需要重新安装, 安装教程参考
Centos7安装MySQL8过程详解笔记 (附相关错误解决办法)
安装mysqlclient包
- python访问mysql数据库 需要第三方包, Django推荐使用mysqlclient.
- 安装命令
pip3 install mysqlclient
(blog) [aaa@qq.com testBlog]# yum install mysqlclient Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * epel: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com No package mysqlclient available. Error: Nothing to do (blog) [aaa@qq.com testBlog]# pip3 install mysqlclient Collecting mysqlclient Using cached mysqlclient-1.4.6.tar.gz (85 kB) ERROR: Command errored out with exit status 1: command: /root/env/blog/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-yl6cmbzb/mysqlclient/setup.py'"'"'; __file__='"'"'/tmp/pip-install-yl6cmbzb/mysqlclient/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-yl6cmbzb/mysqlclient/pip-egg-info cwd: /tmp/pip-install-yl6cmbzb/mysqlclient/ Complete output (12 lines): /bin/sh: mysql_config: command not found /bin/sh: mariadb_config: command not found /bin/sh: mysql_config: command not found Traceback (most recent call last): File "<string>", line 1, in <module> File "/tmp/pip-install-yl6cmbzb/mysqlclient/setup.py", line 16, in <module> metadata, options = get_config() File "/tmp/pip-install-yl6cmbzb/mysqlclient/setup_posix.py", line 61, in get_config libs = mysql_config("libs") File "/tmp/pip-install-yl6cmbzb/mysqlclient/setup_posix.py", line 29, in mysql_config raise EnvironmentError("%s not found" % (_mysql_config_path,)) OSError: mysql_config not found ---------------------------------------- ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
- 上述报错显示mysql_config变量未找到, 需要安装mysql相关依赖
yum install mysql-devel
安装成功后, 继续执行pip3 install mysqlclient
(blog) [aaa@qq.com bin]# pip3 install mysqlclient Collecting mysqlclient Using cached mysqlclient-1.4.6.tar.gz (85 kB) Building wheels for collected packages: mysqlclient Building wheel for mysqlclient (setup.py) ... error ERROR: Command errored out with exit status 1: command: /root/env/blog/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"'; __file__='"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-eexcuz_5 cwd: /tmp/pip-install-rqkddtxm/mysqlclient/ Complete output (31 lines): running bdist_wheel running build running build_py creating build creating build/lib.linux-x86_64-3.6 creating build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/__init__.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/_exceptions.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/compat.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/connections.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/converters.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/cursors.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/release.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/times.py -> build/lib.linux-x86_64-3.6/MySQLdb creating build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants running build_ext building 'MySQLdb._mysql' extension creating build/temp.linux-x86_64-3.6 creating build/temp.linux-x86_64-3.6/MySQLdb gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -Dversion_info=(1,4,6,'final',0) -D__version__=1.4.6 -I/usr/include/mysql -I/root/env/blog/include -I/usr/include/python3.6m -c MySQLdb/_mysql.c -o build/temp.linux-x86_64-3.6/MySQLdb/_mysql.o -m64 MySQLdb/_mysql.c:38:20: fatal error: Python.h: No such file or directory #include "Python.h" ^ compilation terminated. error: command 'gcc' failed with exit status 1 ---------------------------------------- ERROR: Failed building wheel for mysqlclient Running setup.py clean for mysqlclient Failed to build mysqlclient Installing collected packages: mysqlclient Running setup.py install for mysqlclient ... error ERROR: Command errored out with exit status 1: command: /root/env/blog/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"'; __file__='"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-83ml8lxb/install-record.txt --single-version-externally-managed --compile --install-headers /root/env/blog/include/site/python3.6/mysqlclient cwd: /tmp/pip-install-rqkddtxm/mysqlclient/ Complete output (31 lines): running install running build running build_py creating build creating build/lib.linux-x86_64-3.6 creating build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/__init__.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/_exceptions.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/compat.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/connections.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/converters.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/cursors.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/release.py -> build/lib.linux-x86_64-3.6/MySQLdb copying MySQLdb/times.py -> build/lib.linux-x86_64-3.6/MySQLdb creating build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-3.6/MySQLdb/constants running build_ext building 'MySQLdb._mysql' extension creating build/temp.linux-x86_64-3.6 creating build/temp.linux-x86_64-3.6/MySQLdb gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -Dversion_info=(1,4,6,'final',0) -D__version__=1.4.6 -I/usr/include/mysql -I/root/env/blog/include -I/usr/include/python3.6m -c MySQLdb/_mysql.c -o build/temp.linux-x86_64-3.6/MySQLdb/_mysql.o -m64 MySQLdb/_mysql.c:38:20: fatal error: Python.h: No such file or directory #include "Python.h" ^ compilation terminated. error: command 'gcc' failed with exit status 1 ---------------------------------------- ERROR: Command errored out with exit status 1: /root/env/blog/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"'; __file__='"'"'/tmp/pip-install-rqkddtxm/mysqlclient/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-83ml8lxb/install-record.txt --single-version-externally-managed --compile --install-headers /root/env/blog/include/site/python3.6/mysqlclient Check the logs for full command output.
- 上述报错显示mysql_config变量未找到, 需要安装mysql相关依赖
yum install python3-devel
这次安装成功后, 继续执行pip3 install mysqlclient
, 成功安装mysqlclient
配置settings.py文件
- 配置数据库选项
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'djangotest', #数据库名称 'USER': 'root', # 链接数据库的用户名 'PASSWORD': 'root', # 链接数据库的密码 'HOST': '127.0.0.1', # mysql服务器的域名和ip地址 'PORT': '3306', # mysql的一个端口号,默认是3306 } }
生成迁移文件
ORM
-
Django是采用ORM技术来操作数据库的
- ORM(object relation mapping): 对象关系映射, 简单的说这种技术是把数据库中的表与面向对象编程中的类建立映射, 表中的记录与类的对象建立映射, 记录中的字段与对象中的属性建立映射. 然乎使用面向对象编程的语法来完成对数据库的操作
据库 面向对象 表 类 录 对象 段 属性 - 比如执行一条sql语句:
select first_name from person where id=10
ORM可以写成:p=Person.get(10) name = p.first_name
- ORM封装了数据库的底层操作, 给开发者提供了一层接口, 开发者可以使用熟悉的面向对象编程的语法与数据对象直接
- ORM的优点
- 代码变的简单易读
- 避免了繁琐的sql语句
- 不用操作表, 使用面向对象的思路进行编程
- ORM的缺点
- 开发者无法了解底层数据库的操作, 无法自定义一些复杂的sql
- ORM 库的语法和相关设置需要重新学习
迁移文件
- Django中数据模型的代码采用面向对象的思想在app下的models.py中编写, 拥有自己特定的语法格式
- Django并不是把models.py中的数据模型直接转换成数据库中的表, 而是先把数据模型文件转换成迁移文件, 再由迁移文件生成数据库中的表
数据模型 ----> 迁移文件 ----> 数据库中的表 - 迁移文件充当了对象到关系映射的中间使者
- 迁移文件存放在app下的migrations目录下,
具体操作
-
将所有app的数据模型转换成迁移文件 (注意: 生成迁移文件的阶段数据库中还没有表)
python3 manage.py makemigrations
-
只把特定的app下的数据模型转换成迁移文件
python3 manage.py makemigrations app_name
-
查看特定app下特定迁移文件将会生成的sql操作(Django就是根据这些sql操作在数据库中创建表)
python3 manage.py sqlmigrate app_name 000N
(所有生成的迁移文件的文件名都有一个000N的编号)(blog) [aaa@qq.com migrations]# cat 0001_initial.py # Generated by Django 3.0.5 on 2020-04-09 17:23 from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Account', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('user', models.CharField(max_length=40)), ('gender', models.IntegerField()), ('birthday', models.DateField()), ], ), ]```
-
显示迁移文件状态: []代表还未迁移, [X]表示已经迁移完毕, 数据库中生成了相应的表
python3 manage.py showmigrations
-
每执行一次makemigrations操作, django就会把当前的数据模型和migrations文件夹下最新一次的迁移文件中的数据模型进行对比
-
如果相同, 则会提示: no changes, 不产生新文件.
-
如果不同, 则会将这部分不同 涉及的对数据库的更改操作重新生成一个.py文件存放在migrations文件夹下.
-
除了第一次migrations会有大规模建表的create语句外, 后续的都只是在一些已有表上进行修改的操作, 并不会把数据模型整个重构
(blog) [aaa@qq.com migrations]# cat 0002_auto_20200409_1914.py # Generated by Django 3.0.5 on 2020-04-09 19:14 from django.db import migrations class Migration(migrations.Migration): dependencies = [ ('app1', '0001_initial'), ] operations = [ migrations.RenameField( model_name='account', old_name='birthday', new_name='school', ), ]
-
生成数据库的表
-
将所有app的迁移文件都映射到数据库, 全局映射只会映射还没有映射的文件
python3 manage.py migrate
-
指定特定项目的所有迁移文件映射到数据库
python3 manage.py migrate app_name
-
指定特定项目下的特定迁移文件映射到数据库
python3 manage.py migrate app_name 000N
-
数据库中的表只会和最新一次迁移(migrate)的内容保持一致, 因此如果迁移文件的编号已经到了0007, 并且全部迁移文件都已经迁移过一次. 此时如果再次迁移0005, 那么0006和0007的迁移文件产生的更改会全部被取消, 也就是unapplying
(迁移第二个文件)
(迁移三个文件)
(所有文件都以迁移完毕)
再次迁移第一个文件
(第二第三产生的更改全部取) -
如果最新一次的迁移再次被执行, Django显示没有需要迁移的文件
Running migrations: No migrations to apply. Your models have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
参考
下一篇: vue-VueRouter-后台管理案例