Django开发中使用South进行数据库迁移的使用总结
South的详细资料可产看官方文档http://south.readthedocs.org/en/latest
South安装配置
pip install south
安装成功之后,修改django项目中的settings.py文件, 在INSTALLED_APPS中追加 ‘south’, 然后重新执行: ./manage.py syncdb 去创建South迁移跟踪表。
创建初始版本信息
一个new app(还未创建数据库表),在写好其应用里的models.py之后就可以生成数据库表结构的初始版本了。
第1步,执行 ./manage.py schemamigration your_app_name --initial 命令,生成表结构的初始版本,此命令执行后,会自动在你的app目录下创建一个migrations目录并生成0001_initial.py 脚本。
schemamigration只是在你的app中写入一个大的迁移, 真正要在数据库中迁移还要执行第2步。
第2步,执行 ./manage.py migrate your_app_name 命令,在数据库中创建表结构。
如果表结构已经存在, 则可以执行 ./manage.py migrate your_app_name --fake 命令, 告诉South对于已经存在的表结构不再创建。否则,会出现DatabaseError: table ”your_table“ alreadey exists的错误。我第一次使用就在操作失误导致一个表已经建立,出现这种问题。
修改Model字段
之后再对models.py文件作修改之后,如果自己去数据库中修改表的字段是很麻烦的。
第1步,执行 ./manage.py schemamigration your_app_name --auto 命令, south会自动对比你的app中migrations目录下的0001_initial.py并生成0002_auto_xxxx.py文件
第2步,执行 ./manage.py migrate your_app_name 让数据库修改表结构,使新版本表结构生效。
当在models.py的里添加新的属性时, 上述操作默认你添加的属性有一个default值, South会替你给数据库表中已存在的数据在新产生的字段上添加此默认值。如果在添加的属性没有默认值,也就是你在models.py中的类里添加新的属性时的参数null=False。 在执行第1步操作的时候, South会显示出两个选项:
./manage.py schemamigration your_app_name --auto
? The field 'your_model_class_name.new_attribute' does not have a default specified, yet is NOT NULL.
? Since you are adding or removing this field, you MUST specify a default
? value to user for existing rows. Would you like to:
? 1.Quit now, and add a default to the field in models.py
? 2.Specify a one-off value to use for existing columns now
? Please select a choice:
./manage.py schemamigration your_app_name --auto
? The field 'your_model_class_name.new_attribute' does not have a default specified, yet is NOT NULL.
? Since you are adding or removing this field, you MUST specify a default
? value to user for existing rows. Would you like to:
? 1.Quit now, and add a default to the field in models.py
? 2.Specify a one-off value to use for existing columns now
? Please select a choice:
如果你选择1, 那么指令不会做任何事并且退出, 之后你可以去修改你的models.py, 然后添加一个默认值。如果你选择2, 你将会看到一个Python的提示, 让你输入一个值, 用于你的这次迁移为那些已经存在的数据在新的字段上写入你输入的这个值。
? Please select a choice: 2
? Please enter Python code for your one-off default value.
? The datetime module is available, so you can do e.g. datetime.date.today()
>>>
在>>>处输入你想要输入的值。对于你输入的值, 只会用于本次迁移时对已存在数据在新的字段上赋一个值。如果你不想你的model属性有默认值, 这样做是一个很好的选择。选择完选项之后,继续执行第2步完成迁移。
转化已存在app(数据库表已经创建) Converting to An App
有一个已经存在的应用, 而且数据库表已经创建, 要想进行数据库迁移, 需要以下三步:
第1步, 首先确保在settings.py中的INSTALLED_APP里添加了‘south’
第2步, 执行 ./manage.py syncdb 将South表加载(或者说是添加)到数据库中(如果没有, 无法执行迁移)
第3步, 执行 ./manage.py convert_to_south your_app_name -South会自动帮你执行并且假装你是第一次执行迁移。