django 自从 1.7 之后解决了很多问题,并且对于数据库的操作带来了几个新命令用以解决数据迁移问题,今天开始看看文档学习一下。部分内容来源于网络
Django 自 1.7 之后增加了类似 South 的 migration 功能,修改 Model 后可以在不影响现有数据的前提下重建表结构。这真是个千呼万唤始出来的 feature 了
一、migration 介绍
Migrations 其实就是一堆帮助你完成数据库变更和数据迁移的命令,使得你可以用 “Django” 的方式来管理和变更数据库的 schema。
1.1 特性
Migrations让事情变得简单可控:
- 它使得数据库 schema 的调整可以通过Django命令来完成
- 它使得数据库的 schema 和对应的 model 的变更被 track 起来:整个历史都可以版本化在 Git 里面
- 提供了一套匹配 schema 和对应的 fixture 的机制
- 如何和 CI 搭配起来,可以保证代码和数据一致性
1.2 创建 migrations
当有新的 models 创建或者变更的情况下,需要创建一个 migration
# python manage.py makemigrations <appname>
Migrations for 'fault_reports':
0001_initial.py:
- Create model FaultReports
- Create model Log
- Create model User
- 执行完并生成个文件:
<appname>/migrations/0001_initial.py
- 文件是一个夹杂着 mysql 语句的 python 文件,可以手动修改
查看建表语句
python manage.py sqlmigrate <appname> 0001
这里有个注意的问题是那个 0001,其实是 app_lable,默认创建的时候为 0001,可以在 migrations 的目录下看到文件的前缀,其实就是 app_lable
检查所有的配置是否OK
python manage.py check
1.3 应用 migrations
创建对数据库修改及新建。只对新增的内容操作,这样以后有改动就不用删除数据库或表了
# python manage.py migrate
(django182-py2710)➜ ops git:(develop) ✗ ./manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: admin, fault_reports, contenttypes, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... 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 fault_reports.0001_initial... OK
Applying sessions.0001_initial... OK
如果是全新的 app,这两步已经结束了,不需要 syncdb 操作了。总结一下。流程如下
- 1、建立或者更新一个 model
- 2、运行
python manage.py makemigrations <app_name>
- 3、运行
python mange.py migrate <app_name>
- 4、重复前面的步骤
1.4 已有项目进行 migration
日后项目的过程中可能会修改 models 结构,那么就需要如下操作
- 1、运行
./manage.py makemigrations <appname>
- ,Django 会根据你当前 model 来创建那份 initial migrations file。
- 2、运行
./manage.py migrate
- ,Django 会把已经存在的数据库 table 当成是 makemigration 的产物,完成整个 migration
如果运行报错了,那么就需要做一个并不是真 migration 的 fake 了。
./manage.py migrate --fake <appname>
- Mark migrations as run without actually running them
1.5 更多细节
如果你再次运行 python manage.py migrate
,会发现什么都没有发生:这是因为在项目的数据库中有一张 django_migrations 仍然被更新。表,记录了哪些 Migrations 已经被应用过了:无论是运行了 migrate 还是 fake 的,这个表都会被插入一条记录。比如从 South 升级到使用 Django 自带的MigrationsDjango 会检查是否有更新。如果没有,它就 fake 一次,但 django_migrations 仍然被更新。
在少数情况下,确实有需要再次运行某个特定的 Migrations,我们可以在 django_migrations 里面把这个记录删除掉。
在极少数情况下,如果你有需要回退到特定的版本,比如最初的 zero 版本,可以用类似
python manage.py migrate <app_name> zero
参考阅读