使用Django South做Migration

使用South之前铭记:请你一定要相信他的能力,抛弃对他的不信任感。因为South给人的第一印象就是好像每个操作都在抛异常。

South概述

针对django自带的syncdb同步models和数据库的缺陷开发的数据迁移工具,可以作为syncdb的替代,South能够检测对models的更改并同步到数据库.

South基本用法

安装完South之后,要在django项目中使用South,先要将South作为一个App导入项目,所以设置INSTALL_APP添加south
第一次使用South(对于已存在的项目转用South见下一步的介绍)

Python代码

python manage.py schemamigration youappname --initial
# --initial在数据库创建models定义的表,以及South需要的south_migrationhistory表,另外会在youappname目录下面创建一个 migrations 的子目录
#以后每次对models更改后,可以运行以下两条命令同步到数据库

python manage.py schemamigration youappname --auto     #检测对models的更改,生成对应的文件
python manage.py migrate youappnam  #将更改反应到数据库

每次进行migrate操作,south都会去 south_migrationhistory 表查看记录,看migrations目录下面哪些文件没有被执行,然后执行。

迁移到South

对于一个已存在的项目(定义了models,创建了相应的数据库,保存了响应的数据),这时想要使用South替代原来的syncdb只需要一些简单的步骤:
同样需要现在INSTALL_APP里面添加south,然后 python manage.py syncdb #syncdb已经被South更改,用来创建south_migrationhistory表

python manage.py syncdb  #syncdb已经被South更改,用来创建south_migrationhistory表
python manage.py convert_to_south youappname #在youappname目录下面创建migrations目录以及第一次迁移需要的数据库等

South同步原理

对应每次 models的更改执行schemamigration后会在migrations目录下面生成对应此次更改的py文件(South称之为 migrate),文件名形如 0002_autodel_field_notes_create_user.py,同步数据库的时候会顺序(文件名 ASCII排序)执行这些py文件,文件里包含一个Migration的类,里面有两个方法forwards和backwards,将更改同步到数据库会 执行forwards方法,数据库操作失败会调用backwards实现rollback,South还提供了类似回溯的功能。

#You can also specify a specific migration to migrate:
python manage.py migrate 0002_autodel_field_notes_create_user.py
#Note that, if the system has already migrated past the specified migration,
#it will roll back to it instead. If you want to migrate all the way back,
#specify the special migration name zero:
python manage.py migrate zero

常见问题

1. 添加和删除字段时可能会要求输入 default value(django里面models里面的许多字段默认都是null=False)
对于添加字段,输入的默认值必须和models定义的类型匹配,否则同步数据库的时候会报错
对于删除字段的情况,可以随意输入一个value而不管字段的默认类型,可以实现删除,但是并不可取,具体原因可以参见South的实现机制(rollback到删除字段之前会失败)。

2. 如果South在同步数据库的过程中出现错误,则migrations目录下面对应此次更改的python文件不会被执行,可以运行python manage.py migrate –list查看没有执行的py文件,文件名前面没有*表示该文件对应的更改没有反应到数据库,只需删除掉这些有问题的migrate,参照错误提示修改 models再同步即可,也可以直接更改对应的py文件修复错误,然后手动把执行成功的那部分改回来,或者把那部分代码注释掉。

强烈建议把south的官方文档通看一遍,文档写很详细。