Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Django的数据迁移(Data migration)

$
0
0

Django支持ORM模型,我们不必写一条SQL语句,就可以方便使用面向对象管理数据库。数据库的管理可以分为结构迁移和数据迁移。

结构迁移是只是指表的结构改变。我们只需要修改Django的数据模型,然后用 python manage.py makemigrations 自动生成需要执行的数据迁移代码(一般保存在 app/migrations 文件夹下),然后用 python manage.py migrate 执行代码,就可以将变化应用到数据库。

另一种是数据迁移。之前我的做法是,写一个url映射到view,在view中写操作数据库的代码。执行完毕后删掉url。这样做有很多坏处:

将操作数据库开放了(即使可以写管理员权限) 污染url和view的代码 不能将所有有关数据库管理的代码放下 migrations 下面

好处是,如果常用的话,可以作为管理员“维护数据库”的一种方式。但如果是这种用途的话,还是写成一个中规中矩的view比较好。

其实,Django本身就有数据迁移的功能,上面这种做法太“歪门邪道”了。

数据迁移和结构迁移类似,只不过Django不是直接为你生成迁移结构的代码,而是生成一个框架,然后你在这个框架根绝自己的需要写代码。其实这个样子更灵活。

1.生成数据迁移的空白文件

执行下面的命令,生成一个迁移的脚本,等着你填上需要执行的命令。

pythonmanage.py makemigrations --emptyyourappname

生成的空白文件,如下所示。

# -*- coding: utf-8 -*- # Generated by Django A.B on YYYY-MM-DD HH:MM from __future__ import unicode_literals from django.dbimport migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ('yourappname', '0001_initial'), ] operations = [ ] 2.填写数据迁移代码

文件中的 Operations 是空着的,这个地方是需要执行的数据迁移操作。数据操作可以写成函数,然后在 Operations 里面用RunPython运行函数。

函数的第一个变量是app,第二个是 SchemaEditor ,可以用来手动修改数据表的结构。不过不推荐这样做,做自动迁移的时候可能遇到问题。

下面这个迁移是自动根据以前名字的firstname和lastname生成name。导入模型的方式有点特殊,将要做的操作写到Python函数里面,然后在 Operations 里运行Python函数。除了RunPython之外,也可以RunSQL等等。

# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.dbimport migrations, models def combine_names(apps, schema_editor): # 这里不能直接导入Person模型,因为这里的模型要求是特定的一个版本 # 如果直接导入,就会是最新的版本了 Person = apps.get_model("yourappname", "Person") for personin Person.objects.all(): person.name = "%s %s" % (person.first_name, person.last_name) person.save() class Migration(migrations.Migration): initial = True dependencies = [ ('yourappname', '0001_initial'), ] operations = [ migrations.RunPython(combine_names), ] 3.执行migrate命令,应用数据迁移

和应用结构迁移一样,执行下面的命令就可以了。

pythonmanage.pymigrate 4.使用其他app里面的Model

如果RunPython函数里面用到别的app(不是此migrations存在的app)里面的model,应该在 Dependencies 里面模仿例子加上别的app的名字以及最新的migrations依赖。

否则,使用 apps.get_model() 的时候,会遇到 LookupError: No installed app with label 'myappname' 。

下例,app1里面的 migrations 用到了app2的Model。

class Migration(migrations.Migration): dependencies = [ ('app1', '0001_initial'), # 加入app名字,和最后的migrations ('app2', '0004_foobar'), ] operations = [ migrations.RunPython(move_m1), ] 5.参考资料 Django文档,Migrations

Viewing all articles
Browse latest Browse all 9596

Trending Articles