Django迁移

Django迁移

学习目标:python

  • 如何在不编写任何SQL语句的状况下建立数据库表
  • 更改model如何自动修改数据库
  • 如何还原对数据库所作的更改

迁移能解决的问题

若是你不了解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

一、不使用SQL对数据库进行修改

在Django中,若是没有迁移,就必须在使用的时候连接到数据库而且输入一堆SQL命令,或者使用一些图形工具在每次要更改模型定义时修改数据库模式。架构

在Django中,迁移主要是用Python代码完成的,所以除非你有很是高级的需求用法,不然你不须要操做任何SQL。

二、避免重复

若是建立模型后,编写sql语句建立数据库表,则会形成重复现象。

可是从模型中生成迁移,就能确保不会重复

三、确保模型定义和数据模式同步

一般,咱们会有多个数据库实例,例如,团队中每一个开发人员的一个数据库,用于测试的数据库和包含实时数据的数据库。

若是没有迁移,则必须对每一个数据库执行任何模式更改,而且必须跟踪已对哪一个数据库进行了哪些更改。

使用Django Migrations,就能够轻松地使多个数据库与模型保持同步。

四、跟踪版本控制(git)中的数据库模式更改

像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

取消应用迁移

建立以及应用迁移都已经搞定了,知道如如何经过它们去更改数据库模式,可是有些时候咱们可能须要执行一些撤销操做以切换回早期的数据库模式,好比:

  • 测试公司项目的中写的迁移
  • 迁移以后出现bug
  • 同时处理不一样数据库修改的多个功能
  • 想要还原在数据库中具老架构的备份

因此这个时候就须要取消迁移来帮助咱们了。

> 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
  • 根据需求重复操做

这个工做流程在大多数状况下均可以搞定,但若是事情没有按预期进行,还能够列出或者取消应用迁移帮助咱们操做。

相关文章
相关标签/搜索