学习目标:python
若是你不了解Django或者WEB开发,确定是不熟悉数据库迁移的概念的。git
在学习它以前,首先咱们须要明确它是干什么的,Django使用它旨在与关系型数据库结合使用,将数据存储在PostgreSQL
,Mysql
或者SQLite
等关系型数据库管理系统中.github
在关系数据库中,数据以表格形式组织。数据库表具备必定数量的列,但它能够包含任意数量的行。每列都有一个特定的数据类型,如某个特定最大长度的字符串或正整数。全部表及其列及其各自数据类型的描述称为数据库模式。sql
Django支持的全部数据库系统都使用语言SQL来建立,读取,更新和删除关系数据库中的数据。SQL还用于建立,更改和删除数据库表自己。shell
直接使用SQL可能很是麻烦,所以为了让咱们的开发工做更加轻松,Django附带了一个对象关系映射器,简称ORM。ORM将关系数据库映射到面向对象编程的世界。能够在Python中编写Django模型,而不是在SQL中定义数据库表。模型定义数据库字段,这些字段对应于其数据库表中的列。数据库
如下是Django模型类如何映射到数据库表的示例:django
可是只是在Python文件中定义一个模型类并不会使数据库表格无处不在。建立数据库表来存储Django模型是数据库迁移的工做。此外,不管什么时候对模型进行更改(如添加字段),都必须更改数据库。迁移也处理这个问题。编程
如下是Django迁移让咱们的开发工做更加轻松的几种方式:session
在Django中,若是没有迁移,就必须在使用的时候连接到数据库而且输入一堆SQL命令,或者使用一些图形工具在每次要更改模型定义时修改数据库模式。架构
在Django中,迁移主要是用Python代码完成的,所以除非你有很是高级的需求用法,不然你不须要操做任何SQL。
若是建立模型后,编写sql语句建立数据库表,则会形成重复现象。
可是从模型中生成迁移,就能确保不会重复
一般,咱们会有多个数据库实例,例如,团队中每一个开发人员的一个数据库,用于测试的数据库和包含实时数据的数据库。
若是没有迁移,则必须对每一个数据库执行任何模式更改,而且必须跟踪已对哪一个数据库进行了哪些更改。
使用Django Migrations,就能够轻松地使多个数据库与模型保持同步。
像Git这样的版本控制系统很是适合代码,但对数据库模式来讲并非那么多。
因为迁移在Django中是普通的Python,所以您能够将它们放在版本控制系统中,就像任何其余代码同样。
在迁移以前首先得建立一个Django项目,具体怎么建立就不作过多赘述啦。直接开始吧
在作迁移以前,咱们首先要建立模型。在app01/models.py
中添加此类
class User(models.Model): name = models.CharField(max_length=32) password = models.CharField(max_length=64)
一个最简单的用户模型类。
模型建立完成以后的第一件事就是为他建立迁移。
> python manage.py makemigrations
# 有的同窗执行了以上命令后会发现不行,报错了 """ File "manage.py", line 16 ) from exc ^ SyntaxError: invalid syntax """ 这就很难受了,为何呢,由于随着时间的增加,Django的版本已经更新到2.3之后了,而在Django1.7之后,执行以上代码都会报这个错误。咱们须要将python替换成python3 > python3 manage.py makemigrations """ Migrations for 'hello_world': hello_world/migrations/0001_initial.py - Create model User """ 这就成功了!!!
执行成功后,在migrations目录如今包含一个新文件:0001_initial.py
""" 当咱们运行完 makemigrations 命令,若是你没有配置数据库,它还会自动建立db.sqlite3数据库.这个是Django默认的配置,同时也是SQLite独有的配置。若是是其余数据库的话,例如:Mysql、PostgreSQL等,就必须在运行以前本身建立数据库了 """
迁移成功后,咱们接着来查看你的数据库,会发现它虽然被建立出来了,可是他依然是空的。
> python3 manage.py dbshell SQLite version 3.24.0 2018-06-04 14:10:15 Enter ".help" for usage hints. sqlite> .tables sqlite>
虽然如今咱们已经建立了迁移工做,可是要想要实际在数据库中进行任何修改,就必须执行migrate
命令:
> python3 manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, hello_world, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying hello_world.0001_initial... OK Applying sessions.0001_initial... OK
执行完这条命令,会发现有不少输出,根据输出来看,咱们的迁移已经成功应用,那么这些迁移中还有一些咱们不知道的东西,它们来自于哪里呢?
还记得配置文件中的INSTALLED_APPS
吗?其中列出的其余一些应用程序也带有迁移功能,migrate
管理命令默认状况下会为全部已安装的应用程序应用迁移。
再来看一下数据库:
SQLite version 3.24.0 2018-06-04 14:10:15 Enter ".help" for usage hints. sqlite> .tables auth_group django_admin_log auth_group_permissions django_content_type auth_permission django_migrations auth_user django_session auth_user_groups hello_world_user auth_user_user_permissions sqlite>
如今咱们的数据库已经出现了多个表,咱们能够从他们的名字上来了解他们的做用。
# 能够经过.schema命令查看已经生成的表 sqlite> .schema --indent hello_world_user CREATE TABLE IF NOT EXISTS "hello_world_user"( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(32) NOT NULL, "password" varchar(64) NOT NULL ); """ .schema命令打印出CREATE将执行以建立表的语句。该参数--indent将sql语句格式化。即便不熟悉SQL语法,也能够看到hello_world_user表的模式反映了user模型的字段。 """
若是你再次进行迁移的话,会发现不会将全部的模型表从新执行一遍,由于Django会记住已经应用了那些迁移,不会对已经迁移过的,在从新运行。
你的model文件必定不是一成不变的,随着你项目的完善,功能的添加,你的模型确定会发生变化,能够添加、删除字段或者更改类型还有选项。
在更改模型类的时候,确定还须要更改用于存储这些模型的数据库表。若是模型定义与当前数据模式不匹配,极可能就会报错:django.db.utils.OperationalError
具体更改方法:
依次执行: > python3 manage.py makemigrations > python3 manage.py migrate
若是想要知道项目中存在那些迁移,能够直接经过如下命令查看
python3 manage.py showmigrations
建立以及应用迁移都已经搞定了,知道如如何经过它们去更改数据库模式,可是有些时候咱们可能须要执行一些撤销操做以切换回早期的数据库模式,好比:
因此这个时候就须要取消迁移来帮助咱们了。
> python3 manage.py migrate hello_world 0001_initial
执行它就能够将迁移取消应用,也意味着对数据库的更改也被取消了
取消应用迁移不会删除其迁移文件。下次运行该migrate
命令时,将再次应用迁移。
""" 不要将未应用的迁移与您最经常使用的文本编辑器中的撤消操做混淆。 并不是全部数据库操做均可以彻底还原。若是从模型中删除字段,建立迁移并应用它,Django将从数据库中删除相应的列。 取消应用迁移将从新建立列,但它不会带回存储在该列中的数据! """
Django迁移的基本步骤:
python3 manage.py makemigrations <app name(可不写)>
python3 manage.py migrate
迁移全部内容或python3 manage.py migrate <app name>
迁移单个app这个工做流程在大多数状况下均可以搞定,但若是事情没有按预期进行,还能够列出或者取消应用迁移帮助咱们操做。