django south 使用教程

一、下载与安装

south安装包下载地址:https://bitbucket.org/andrewgodwin/south/

south文档:http://south.readthedocs.org/en/latest/

二、south简介

Django 的第三方 app South 就是专门做数据库表结构自动迁移工作,Jacob Kaplan-Moss 曾做过一次调查,South 名列最受欢迎的第三方 app。事实上,它现在已经俨然成为 Django 事实上的数据库表迁移标准,很多第三方 app 都会带 South migrations 脚本。

三、回顾syncdb

syncdb是db synchronization的缩写,意思是数据库同步。

syncdb 命令是同步你的模型到数据库的一个简单方法。 它会根据 INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。 需要注意的是, syncdb 并不能将模型的修改或删除同步到数据库;如果你修改或删除了一个模型,并想把它提交到数据库,syncdb并不会做出任何处理。

如果你再次运行 python manage.py syncdb ,什么也没发生,因为你没有添加新的模型或者添加新的app。因此,运行python manage.py syncdb总是安全的,因为它不会重复执行SQL语句。
知识总结:迁移( migrations?)

四、为什么用south

对于二、三两点,可知syncdb的不足,如果更改了models,如添加一列等此时syncdb就没有用武之地了,如果硬手工修改表结构不仅容易出错,又不安全,并非权宜之计,而south却能很好的解决该问题。

south特性:

(1)、自动迁移:south可自动检测你的Models.py文件的改变,自动写入migrations去匹配你所做的改变。

(2)、数据库独立性:完全与数据库无关的,支持五个不同的数据库后端。这样就无需再关注于数据库方向,而专注与django。

(3)、app艺术:south依赖app,south本身也是django的第三方app,再在使用的时候单独作用于每个app下,进行迁移,同步。

(4)、VCS处理:south也能处理如果别人提交迁移到相同的应用程序作为你和他们冲突。

你写的迁移(migrations),它告诉south如何从一个版本升级到下一个,和通过串接在一起你可以移动这些迁移向前(或向后)通过历史数据库的模式。south也能创建新的model

五、快速指南

1、安装完South之后,要在django项目中使用South,先要将South作为一个App导入项目,所以设置INSTALL_APP添加south 第一次使用South。

2、manage.py syncdb 用来创建south_migrationhistory表。

3、manage.py convert_to_south youappname #在youappname目录下面创建migrations目录以及第一次迁移需要的0001_initial.py文件

4、如果改变了model里的内容,./manage.py schemamigration youappname --auto #检测对models的更改

manage.py migrate youappnam #将更改反应到数据库(如果出现表已存在的错误,后面加 --fake)

如果第一次使用:
1、./manage.py schemamigration youappname --initial # youappname目录下面创建一个migrations的子目录(注意!!就算有多个app,也只要initial一个就可以)
2、./manage.py syncdb #初始化数据表等

#以后每次对models更改后,可以运行以下两条命令同步到数据库
3、./manage.py schemamigration youappname --auto #检测对models的更改
4、./manage.py migrate youappnam #将更改反应到数据库(如果出现表已存在的错误,后面加 --fake)

推荐教程:

http://codinn.com/people/brant/notes/110932/

http://a280606790.iteye.com/blog/1107657

六、深入基础教程(首度使用)

1、新建models

新建southtut app,然后定义models如下:

class Knight(models.Model):
    name = models.CharField(max_length=100)
    of_the_round_table = models.BooleanField()
然后使用 syncdb 为它创建一个迁移。

2、第一个迁移

south创建迁移有以下两种方式:自动和手动,对于新手来说推荐两种自动方式:--auto和--initial.

我们使用manage.py schemamigration app_name时候:(schema  migration:模式 迁移,简化为schemamigration)

--auto:作用于旧的(已经存在)的迁移(migration),对一些改变做出迁移工作,如增加字段等。

--initial:针对新的(尚未存在)的迁移,将创建表和索引对应到app 的models下。这是当你定义好model后的初步使用,如同syncdb一样。

接下来开始创建第一个迁移

复制代码
E:\project\demo>manage.py schemamigration southtut --initial
Creating migrations directory at 'E:\project\demo\southtut\migrations'...#创建迁移目录migrations
Creating __init__.py in 'E:\project\demo\southtut\migrations'...#创建__init__.py
+ Added model southtut.Knight                                  #增加model
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate southtut#创建版本控制
复制代码
完了之后,在项目目录结构中可见以下改变:



当然也创建了该model:southtut.Knight

那么接下来就应用新的迁移,注意如果已经存在该model则使用 --fake

复制代码
E:\project\demo>manage.py migrate southtut --fake  #启动
Running migrations for southtut:                   #启动该app下的migrations
- Migrating forwards to 0001_initial.             #正向前迁移
> southtut:0001_initial
   (faked)
复制代码
3、应用改变

这里添加一个字段,要把给字段给同步上去。

class Knight(models.Model):
    name = models.CharField(max_length=100)
    of_the_round_table = models.BooleanField()
    dances_whenever_able = models.BooleanField()  #新增
那么接下来就是同步了,此时分两个步骤:

(1)、创建迁移:manage.py schemamigration southtut --auto

复制代码
E:\project\demo>manage.py schemamigration southtut --auto  #此时用 --auto
+ Added field dances_whenever_able on southtut.Knight     #做出的改变
Created 0002_auto__add_field_knight_dances_whenever_able.py. #创建迁移版本
You can now apply this migration with: ./manage.py migrate southtut
复制代码
(2)、应用:manage.py migrate southtut

复制代码
E:\project\demo>manage.py migrate southtut
Running migrations for southtut:
- Migrating forwards to 0002_auto__add_field_knight_dances_whenever_able.
> southtut:0002_auto__add_field_knight_dances_whenever_able
- Loading initial data for southtut.
No fixtures found.
复制代码
完成之后,则发现已经添加了该字段



七、深入基础教程(迁移使用)

1、基本流程

对于已经之前已经存在的model,如果我们使用south则不能使用上面的步骤。比如说,我有一个名为other的app下model早已建立并且同步至数据库,那么我想要用south,那么就要作如下处理了。

复制代码
#已存在的model且里面存有数据
class Contact(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    comment = models.CharField(max_length=100)
    def __unicode__(self):
        return self.name
    class Meta:
        db_table='contact'
复制代码
ok,我要用这个,且在model里动了手脚。

#Contact
...
age = models.IntegerField()  #添加
那么使用south如下:

(1)、创建迁移:(--auto)

manage.py schemamigration other --auto
.....#省略
(2)、应用:

manage.py migrate other
#...省略
流程给出了,但是为什么省略输出的部分呢,因为这里涉及到一个知识点,就是Defaults:

2、defaults

对于上面southtut app model存在BooleanField,则该字段默认的default=False,然而对于其他字段,可能没有定义默认字段,如果列为空,既null=True,那么新生成的列就没有威胁了,否则就必须给出默认值,因为对于已经存在数据的model,新的字段不可能没有值。一些数据库后端将让你添加列,如果表是空的,而有些会拒绝彻底。

针对这种情况,south将会给出选择并执行

#Contact
...
website = models.CharField(max_length=100,null=False)  #新增
..
复制代码
E:\project\demo>manage.py schemamigration other --auto
? The field 'Contact.website' does not have a default specified, yet is NOT NULL.   #问题
? Since you are adding this field, you MUST specify a default value to use for existing rows. Would you like to:
?  1. Quit now, and add a default to the field in models.py    #退出,在models手动添加默认值
?  2. Specify a one-off value to use for existing columns now  #指定默认值
? Please select a choice:
复制代码
复制代码
.....
? 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()
>>> 'http://www.google.com'             #指定的默认值
+ Added field website on other.Contact  #添加成功
Created 0006_auto__add_field_contact_website.py. You can now apply this migration with: ./manage.py migrate other
复制代码
复制代码
#应用
E:\project\demo>manage.py migrate other
Running migrations for other:
- Migrating forwards to 0006_auto__add_field_contact_website.
> other:0006_auto__add_field_contact_website
- Loading initial data for other.No fixtures found.
复制代码
3、Uniques

还有一点重要的是unique属性

复制代码
class Contact(models.Model):
    name = models.CharField(max_length=30,unique=True)#更改了
    email = models.EmailField()
    comment = models.CharField(max_length=100)
    website = models.CharField(max_length=100,null=False)  #新增
    def __unicode__(self):
        return self.name
    class Meta:
        db_table='contact'
复制代码
复制代码
E:\project\demo>manage.py schemamigration other --auto
+ Added unique constraint for ['name'] on other.Contact
Created 0007_auto__add_unique_contact_name.py. You can now apply this migration
with: ./manage.py migrate other

#还可以这样:
E:\project\demo>manage.py schemamigration --auto other
复制代码
然后再manage.py migrate southtut 就ok了。

4、ManyToMany fields

south能够检测多对多字段,South will create the table the ManyToMany represents, and when you remove the field, the table will be deleted.

你可能感兴趣的:(Django)