Django模型修改及数据迁移

原文地址:http://www.cnblogs.com/linxiyue/p/4106514.html

Django模型修改及数据迁移

Migrations

Django中对Model进行修改是件麻烦的事情,syncdb命令仅仅创建数据库里还没有的表,它并不对已存在的数据表进行同步修改,也不处理数据模型的删除。 如果你新增或修改数据模型里的字段,或是删除了一个数据模型,你需要手动在数据库里进行相应的修改或者使用South。Django 1.7中已经集成了South的代码,提供了3个新命令:

  • migrate: 用于执行迁移动作,具有syncdb的功能
  • makemigrations: 基于当前的model创建新的迁移策略文件
  • sqlmigrate: 显示迁移的SQL语句,具有sqlall的功能

使用起来很简单,对Model做了修改后,使用makemigrations记录修改:

1
2
3
4
$ python manage.py makemigrations
Migrations  for  'books' :
   0003_auto .py:
     -  Alter field author on book

你的Model会被扫描, 然后与migrations文件夹中以前的版本作比较, 然后生成本次迁移文件。

有了新的migration文件,就可以使用migrate修改数据库模式:

1
2
3
4
5
6
7
8
9
10
11
$ python manage.py migrate
Operations to perform:
   Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
   Apply  all  migrations: books
Synchronizing apps without migrations:
   Creating tables...
   Installing custom SQL...
   Installing indexes...
Installed  0  object (s)  from  0  fixture(s)
Running migrations:
   Applying books. 0003_auto ... OK

也可以针对单独的app生成migration:

1
$ python manage.py makemigrations your_app_label

也可以对数据库中的数据进行修改,首先建立一个空的migration文件:

1
python manage.py makemigrations  - - empty yourappname

文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
from  django.db  import  models, migrations
 
class  Migration(migrations.Migration):
 
     dependencies  =  [
         ( 'yourappname' '0001_initial' ),
     ]
 
     operations  =  [
     ]

如果想修改某个Model例如Person的数据,设置其name字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: utf-8 -*-
from  django.db  import  models, migrations
 
def  combine_names(apps, schema_editor):
     # We can't import the Person model directly as it may be a newer
     # version than this migration expects. We use the historical version.
     Person  =  apps.get_model( "yourappname" "Person" )
     for  person  in  Person.objects. all ():
         person.name  =  "%s %s"  %  (person.first_name, person.last_name)
         person.save()
 
class  Migration(migrations.Migration):
 
     dependencies  =  [
         ( 'yourappname' '0001_initial' ),
     ]
 
     operations  =  [
         migrations.RunPython(combine_names),
     ]

最后运行 python manage.py migrate即可。这样Person中的所有对象的name字段都设置好了。

依据Model修改关系数据库是开发中的一个重要的问题,解决这个问题可以提升开发速度,不过要在生产环境中随便使用migrate操作数据库还是很危险的,有时候需要手动修改数据库。

手动修改数据库

当处理模型修改的时候:

  • 如果模型包含一个未曾在数据库里建立的字段,Django会报出错信息。 当你第一次用Django的数据库API请求表中不存在的字段时会导致错误。
  • Django不关心数据库表中是否存在未在模型中定义的列。
  • Django不关心数据库中是否存在未被模型表示的table。

添加字段

  1. 在你的模型里添加字段。下例向Book模型添加num_pages字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class  Book(models.Model):
         title  =  models.CharField(max_length = 100 )
         authors  =  models.ManyToManyField(Author)
         publisher  =  models.ForeignKey(Publisher)
         publication_date  =  models.DateField()
         * * num_pages  =  models.IntegerField(blank = True , null = True ) * *
     
         def  __unicode__( self ):
             return  self .title 
  1. 运行manage.py sqlall yourappname来测试模型新的CREATE TABLE语句。 

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE  "books_book"  (
         "id"  serial NOT NULL PRIMARY KEY,
         "title"  varchar( 100 ) NOT NULL,
         "publisher_id"  integer NOT NULL REFERENCES  "books_publisher"  ( "id" ),
         "publication_date"  date NOT NULL,
         "num_pages"  integer NULL
    );
  1. 开启你的数据库的交互命令界面(比如,psql或者mysql,或者可以使用manage.py dbshell。 执行ALTER TABLE语句来添加新列。

    1
    ALTER TABLE books_book ADD COLUMN num_pages integer;  

添加 非NULL 字段

先创建 NULL 型的字段,然后将该字段的值填充为某个默认值,然后再将该字段改为 NOT NULL 型

1
2
3
4
5
BEGIN;
ALTER TABLE books_book ADD COLUMN num_pages integer;
UPDATE books_book  SET  num_pages = 0 ;
UPDATE books_book  SET  num_pages  =  NULL;
COMMIT;

或者

1
ALTER TABLE <YourTable> ADD <NewColumn> <NewColumnType> NOT NULL DEFAULT <DefaultValue>;

添加ForeignKey或ManyToManyField

添加外键即是添加key_id的integer字段,添加多对多字段是创建一个新的数据表。

删除字段

比较简单,将表中的某列删掉即可

1
ALTER TABLE books_book DROP COLUMN num_pages;

使用sqlite3时,会有些麻烦,sqlite3不支持删除列操作,只有有限地 ALTER TABLE 支持。你可以使用它来在表的末尾增加一列,可更改表的名称。 如果需要对表结构做更复杂的改变,则必须重新建表。重建时可以先将已存在的数据放到一个临时表中,删除原表, 创建新表,然后将数据从临时表中复制回来。

如,假设有一个 t1 表,其中有 "a", "b", "c" 三列, 如果要删除列 c :

1
2
3
4
5
6
7
8
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;

删除多对多关联字段

删掉多对多关联的数据表即可

1
DROP TABLE books_book_authors;

删除模型

删除数据表即可

1
DROP TABLE books_book;

数据迁移

django 项目提供了一个导出的方法 python manage.py dumpdata, 不指定 appname 时默认为导出所有的app

1
python manage.py dumpdata myapp > myapp.json

导出的文件内容格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
   {
     "model" "myapp.person" ,
     "pk" 1 ,
     "fields" : {
       "first_name" "John" ,
       "last_name" "Lennon"
     }
   },
   {
     "model" "myapp.person" ,
     "pk" 2 ,
     "fields" : {
       "first_name" "Paul" ,
       "last_name" "McCartney"
     }
   }
]

数据导入:

1
python manage.py loaddata myapp.json

导出用户数据:

1
python manage.py dumpdata auth > auth.json
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值