python第三方库系列之三--数据库迁移工具south库

来源:互联网 发布:锁机软件生成器 编辑:程序博客网 时间:2024/05/21 14:45

    如果再见不能红着眼,是否还能红着脸~

    前言:django提供syncdb命令,用于从models自动生成数据库。但在models结构变化后,syncdb并无法自动实现数据库的更新。South组件即是为了解决该问题而出现的。基本上可以作为syncdb的替代。

    假设我们创建了一个名叫youappnameapp,分两种情况:1. 开始就是用了south; 2. 中途加入south

一、对于第一种情况,步骤如下:

1. 在APP_INSTALL中加入south

2. 运行以下命令

   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  #将更改反应到数据库</strong>


二、对于第二种情况,就是有一个已存在的项目(定义了models,创建了相应的数据库,保存了响应的数据),这时想要使用South替代原来的syncdb,只需要一些简单的步骤:

1. 在APP_INSTALL中加入south

2. 运行以下命令,用来在数据库中创建south_migrationhistory表

python manage.py syncdb #syncdb已经被South更改,用来创建south_migrationhistory表

3. 在youappname文件夹下建立migrations目录

python manage.py convert_to_south youappname #在youappname目录下面创建migrations目录以及第一次迁移需

4. 以后在这个项目中就可以正常使用South了


    在很多应用场景中,我们已经用syncdb将数据库给创建好了。这时候运行上面的migrate命令将会提示相关表已经存在,命令执行失败。这 时候我们需要告诉south需要跳过某些migrate操作。上面的命令将告诉south,系统已经执行过了0001号数据库迁移脚本。
    python manage.py migrate southtut 0001 --fake

    接下来我们对models进行了某些改动,修改后增减了某些字段。该命令将自动生成数据库的迁移脚本。在migrations目录下可以看到新增加了文件0002_xxx.py,该文件即是此次models改 动的数据库升级脚本。打开文件后可看到其中有一个类Migration,类中有两个方法forwards和backwards。这两个方法分别实现数据库 升级和会滚时对数据库的操作,具体指令的含义参考south的数据库API。


三、South同步原理

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


四、常见问题

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

2. 杀手锏
     如果South在同步数据库的过程中出现错误,则migrations目录下面对应此次更改的python文件不会被执行,可以运行python manage.py migrate --list查看没有执行的py文件,文件名前面没有*表示该文件对应的更改没有反应到数据库,只需删除掉这些有问题的migrate,参照错误提示修改 models再同步即可,也可以直接更改对应的py文件修复错误



0 0