django 1.8 官方文档翻译: 2-4-4 编写迁移

简介: Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html编写数据库迁移这一节介绍你可能遇到的在不同情况下如何分析和编写数据库迁移. 有关迁移的入门资料,请查看 the topic guide.数据迁移和多数据库在使用多个数据库时,需要解决是否针对某个特定数据库运行迁移。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。

交流群:467338606

网站:http://python.usyiyi.cn/django/index.html

编写数据库迁移

这一节介绍你可能遇到的在不同情况下如何分析和编写数据库迁移. 有关迁移的入门资料,请查看 the topic guide.

数据迁移和多数据库

在使用多个数据库时,需要解决是否针对某个特定数据库运行迁移。例如,你可能 只 想在某个特定数据库上运行迁移。

为此你可以在RunPython中通过查看schema_editor.connection.alias 属性来检查数据库连接别名:

from django.db import migrations

def forwards(apps, schema_editor):
    if not schema_editor.connection.alias == 'default':
        return
    # Your migration code goes here

class Migration(migrations.Migration):

    dependencies = [
        # Dependencies to other migrations
    ]

    operations = [
        migrations.RunPython(forwards),
    ]
Django 1.8 中新增。

你也可以提供一个提示作为 **hints参数传递到数据库路由的allow_migrate() 方法:

myapp/dbrouters.py
class MyRouter(object):

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if 'target_db' in hints:
            return db == hints['target_db']
        return True

然后,要在你的迁移中利用,执行以下操作:

from django.db import migrations

def forwards(apps, schema_editor):
    # Your migration code goes here

class Migration(migrations.Migration):

    dependencies = [
        # Dependencies to other migrations
    ]

    operations = [
        migrations.RunPython(forwards, hints={'target_db': 'default'}),
    ]

如果你的RunPython或者RunSQL操作只对一个模型有影响,最佳实践是将model_name作为提示传递,使其尽可能对路由可见。这对可复用的和第三方应用极其重要。

添加唯一字段的迁移

如果你应用了一个“朴素”的迁移,向表中一个已存在的行中添加了一个唯一的非空字段,会产生错误,因为位于已存在行中的值只会生成一次。所以需要移除唯一性的约束。

所以,应该执行下面的步骤。在这个例子中,我们会以默认值添加一个非空的UUIDField字段。你可以根据你的需要修改各个字段。

  • 把default=…和unique=True参数添加到你模型的字段中。在这个例子中,我们默认使用uuid.uuid4。
  • 运行 makemigrations 命令。
  • 编辑创建的迁移文件。

生成的迁移类看上去像这样:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0003_auto_20150129_1705'),
    ]

    operations = [
        migrations.AddField(
            model_name='mymodel',
            name='uuid',
            field=models.UUIDField(max_length=32, unique=True, default=uuid.uuid4),
        ),
    ]

你需要做三处更改:

  • 从已生成的迁移类中复制,添加第二个AddField操作,并改为AlterField。
  • 在第一个AddField操作中,把unique=True改为 null=True,这会创建一个中间的null字段。
  • 在两个操作之间,添加一个RunPython或RunSQL操作为每个已存在的行生成一个唯一值(例如UUID)。

最终的迁移类应该看起来是这样:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
import uuid

def gen_uuid(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    for row in MyModel.objects.all():
        row.uuid = uuid.uuid4()
        row.save()

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0003_auto_20150129_1705'),
    ]

    operations = [
        migrations.AddField(
            model_name='mymodel',
            name='uuid',
            field=models.UUIDField(default=uuid.uuid4, null=True),
        ),
        # omit reverse_code=... if you don't want the migration to be reversible.
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
        migrations.AlterField(
            model_name='mymodel',
            name='uuid',
            field=models.UUIDField(default=uuid.uuid4, unique=True),
        ),
    ]

现在你可以像平常一样使用migrate命令应用迁移。

注意如果你在这个迁移运行时让对象被创建,就会产生竞争条件(race condition)。在AddField之后, RunPython之前创建的对象会覆写他们原始的uuid。

相关文章
|
4月前
|
Linux Docker Python
一条命令迁移 django 服务
一条命令迁移 django 服务
32 0
|
7月前
|
关系型数据库 MySQL 数据库
Django迁移数据库报错你遇到了吗?
最新版本创建应用后,迁移数据库报错怎么办?
|
8月前
|
Oracle 关系型数据库 MySQL
[Python]Django模型的定义 & 修改数据库引擎 & 迁移
[Python]Django模型的定义 & 修改数据库引擎 & 迁移
|
9月前
|
SQL 关系型数据库 MySQL
django迁移了数据库
我们定义好model,执行两个命令Django 就帮我们迁移了数据库。这是因为我们使用了 Python 内置的 SQLite3 数据库。
85 0
|
Oracle 关系型数据库 MySQL
Django - MySQL配置信息与迁移
首先了解一下,数据库简单分类: 1、sqlite3(免费) 1.1、是一个嵌入式的关系型数据库; 1.2、主要在移动端使用,属于小型的关系型数据库 2、中型数据库:mysql(甲骨文、免费)、sqlserver(微软) 3、大型的数据库:oracle、DB2
113 0
|
Oracle 关系型数据库 MySQL
Django入门:第五章、模型建立与迁移
Django入门:第五章、模型建立与迁移
161 0
Django入门:第五章、模型建立与迁移
|
Shell 数据库 数据安全/隐私保护
HelloDjango 系列教程:Django 迁移、操作数据库
HelloDjango 系列教程:Django 迁移、操作数据库 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 我们已经编写了博客数据库模型的代码,但那还只是 Python 代码而已,django 还没有把它翻译成数据库语言,因此实际上这些数据库表还没有真正的在数据库中创建。
1143 0
|
SQL 测试技术 数据库
django 1.8 官方文档翻译: 2-6-3 提供初始数据
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 为模型提供初始数据 当你首次建立一个应用的时候,为你的数据库预先安装一些硬编码的数据,是很有用处的。
|
数据库 Python 数据库连接
django 1.8 官方文档翻译: 2-6-2 遗留的数据库
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 将遗留数据库整合到Django 虽然Django最适合用来开发新的应用,但也可以将它整合到遗留的数据库中。
|
SQL 缓存 数据库
django 1.8 官方文档翻译: 2-6-4 数据库访问优化
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 数据库访问优化 Django的数据库层提供了很多方法来帮助开发者充分的利用他们的数据库。