Django模型修改及数据迁移
Migrations
Django中对Model进行修改是件麻烦的事情,syncdb命令仅仅创建数据库里还没有的表,它并不对已存在的数据表进行同步修改,也不处理数据模型的删除。 如果你新增或修改数据模型里的字段,或是删除了一个数据模型,你需要手动在数据库里进行相应的修改或者使用South。Django 1.7中已经集成了South的代码,提供了3个新命令:
- migrate: 用于执行迁移动作,具有syncdb的功能
- makemigrations: 基于当前的model创建新的迁移策略文件
- sqlmigrate: 显示迁移的SQL语句,具有sqlall的功能
使用起来很简单,对Model做了修改后,使用makemigrations记录修改:
$ python manage.py makemigrations
Migrations for 'books':
0003_auto.py:
- Alter field author on book
你的Model会被扫描, 然后与migrations文件夹中以前的版本作比较, 然后生成本次迁移文件。
有了新的migration文件,就可以使用migrate修改数据库模式:
$ 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:
$ python manage.py makemigrations your_app_label
也可以对数据库中的数据进行修改,首先建立一个空的migration文件:
python manage.py makemigrations --empty yourappname
文件的内容如下:
# -*- coding: utf-8 -*-
from django.db import models, migrations class Migration(migrations.Migration): dependencies = [
('yourappname', '0001_initial'),
] operations = [
]
如果想修改某个Model例如Person的数据,设置其name字段:
# -*- 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。
添加字段
在你的模型里添加字段。下例向Book模型添加num_pages字段:
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
运行manage.py sqlall yourappname来测试模型新的CREATE TABLE语句。
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
);
开启你的数据库的交互命令界面(比如,psql或者mysql,或者可以使用manage.py dbshell。 执行ALTER TABLE语句来添加新列。
ALTER TABLE books_book ADD COLUMN num_pages integer;
添加 非NULL 字段
先创建 NULL 型的字段,然后将该字段的值填充为某个默认值,然后再将该字段改为 NOT NULL 型
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;
或者
ALTER TABLE <YourTable> ADD <NewColumn> <NewColumnType> NOT NULL DEFAULT <DefaultValue>;
添加ForeignKey或ManyToManyField
添加外键即是添加key_id的integer字段,添加多对多字段是创建一个新的数据表。
删除字段
比较简单,将表中的某列删掉即可
ALTER TABLE books_book DROP COLUMN num_pages;
使用sqlite3时,会有些麻烦,sqlite3不支持删除列操作,只有有限地 ALTER TABLE 支持。你可以使用它来在表的末尾增加一列,可更改表的名称。 如果需要对表结构做更复杂的改变,则必须重新建表。重建时可以先将已存在的数据放到一个临时表中,删除原表, 创建新表,然后将数据从临时表中复制回来。
如,假设有一个 t1 表,其中有 "a", "b", "c" 三列, 如果要删除列 c :
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;
删除多对多关联字段
删掉多对多关联的数据表即可
DROP TABLE books_book_authors;
删除模型
删除数据表即可
DROP TABLE books_book;
数据迁移
django 项目提供了一个导出的方法 python manage.py dumpdata, 不指定 appname 时默认为导出所有的app
python manage.py dumpdata myapp > myapp.json
导出的文件内容格式:
[
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
}
}
]
数据导入:
python manage.py loaddata myapp.json
导出用户数据:
python manage.py dumpdata auth > auth.json
Django模型修改及数据迁移的更多相关文章
- 创建app子应用,配置数据库,编写模型,进行数据迁移
文章目录 web开发django模型 1.创建app子应用 2.配置子应用 3.使用 4.配置子应用管理自已的路由 django数据库开发思维与ORM 1.创建数据库 2.配置数据库 3.安装pymy ...
- CoreData 从入门到精通(六)模型版本和数据迁移
前面几篇文章中讲的所有内容,都是在同一个模型版本上进行操作的.但在真实开发中,基本上不会一直停留在一个版本上,因为需求是不断变化的,说不定什么时候就需要往模型里添加新的字段,添加新的模型,甚至是大规模 ...
- laravel模型建立和数据迁移和数据填充(数据填充没有成功)未完
开始创建我们的第一个 Article 模型及其对应迁移文件了,我们在项目根目录运行如下 Artisan 命令一步到位: php artisan make:model Article -m -m 是 - ...
- django 模型增加字段后迁移失败
任 务:已有models.py文件中定义了 ad类(用来描述广告数据库表结构).现在想增加四个新字段:ad_show_type,big_video_url,is_full_screen,vi ...
- django模型:为已存在的表建立模型
为已经存在的表建立模型:参考https://blog.csdn.net/opera95/article/details/78200024 为已经存在的表建立模型1.python manage.py i ...
- Django添加模型无法数据迁移解决方法
用Django开发一款博客,按照教程一步步写下来,发现当我创建一个模型blogpost的时候,使用数据迁移 python manage.py migrate 提示 Operations to perf ...
- codefirst数据迁移技术,在保留数据库数据下实现对模型的修改并映射到数据库
一前言 这是我的处女作,写的不好的地方还望指出共同讨论.EF的数据访问方式有三种DbFirst,ModelFirst,还有本文要提到的CodeFirst 三者都是以ORM的方式建立.本人之前学习的.n ...
- 【Python】Django删除数据迁移记录
find . -path "*migrations*" -name "*.py" -not -path "*__init__*" -exec ...
- 数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案
作为一种数据存储层面上的水平伸缩解决方案,数据库Sharding技术由来已久,很多海量数据系统在其发展演进的历程中都曾经历过分库分表的Sharding改造阶段.简单地说,Sharding就是将原来单一 ...
随机推荐
- 忘记linux root密码怎么办?
摘自:<鸟哥的Linux私房菜> 常常有些朋友在配置好了Linux之后,结果root密码给他忘记去!要重新安装吗?不需要的, 你只要以单人维护模式登陆即可更改你的root密码喔!由于lil ...
- cadence通过孔焊盘的制作
1 首先制作flash 1)制作焊盘前先计算好各项数据 thermal relief(热风焊盘):内径(ID)= 孔径 +20mil 外径(OD)= Anti_pad的直径= Regular p ...
- Android Studio快速开发之道(各种语法糖)
现如今开发越来越追求效率和节奏,节省出时间做更多的事情,除了开发技术上的封装等,开发工具的使用技巧也是很重要的,今天就根据自己的经验来给大家介绍一下Android Studio快速开发之道. Post ...
- Arrays.asList方法总结
import java.util.Arrays; import java.util.List; /** * * 本类演示了Arrays类中的asList方法 * 通过四个段落来演示,体现出了该方法的相 ...
- Java 线程池框架核心代码分析
前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executor接口,提供了一种标准的方法将任务的提交过 ...
- Java对象的序列化与反序列化
序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等.在网络传输过程中,可以是字节或是 ...
- layoutSubviews -- setNeedsLayout -- layoutIfNeeded -- 区别
-layoutSubviews方法:这个方法,默认没有做任何事情,需要子类进行重写-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但 ...
- 修改myeclipse的jsp模板
在myeclipse的安装目录下: C:\Users\Seeker\AppData\Local\MyEclipse Professional\plugins 找到com.genuitec.eclips ...
- 20145120 《Java程序设计》第3周学习总结
20145120 <Java程序设计>第3周学习总结 教材学习内容总结 基本类型与类类型的概念 在java里使用数组和字符串 封装的概念 在java定义函数 重载的概念 static的概念 ...
- 2729:[HNOI2012]排队 - BZOJ
题目描述 Description某中学有n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人 ...