Django Migration RunSQL条件数据库类型

时间:2015-09-03 20:06:31

标签: django django-orm django-migrations django-database

我正在尝试使用migrations.RunSQL Django迁移来运行一些任意的SQL代码。我想仅针对某些db后端运行此迁移(例如仅针对postgres)。

我会考虑to use something like this,但我在Migration课程中看不到数据库连接信息。

5 个答案:

答案 0 :(得分:7)

我只是有同样的需要。我必须编辑一个设置序列初始值的迁移,它适用于postgres但不适用于sqlite。以下是我根据Daniel链接到的文档将RunSQL包装在RunPython中的方法。

from django.db import migrations


def forwards(apps, schema_editor):
    if not schema_editor.connection.vendor == 'postgres':
        return
    migrations.RunSQL(
        "alter sequence api_consumer_id_seq restart with 1000500;")


class Migration(migrations.Migration):
    dependencies = [
        ('api', '0043_auto_20160416_2313'),
    ]

    operations = [
        migrations.RunPython(forwards),
    ]

答案 1 :(得分:5)

以下是我解决问题的方法,因为我无法让private Date createdAtRunSQL内工作。值得庆幸的是,RunPython对象有一个execute() method

schema_editor

答案 2 :(得分:4)

我今天解决了类似的问题 - 需要执行迁移才能创建新模型,但仅适用于postgres数据库 - 我发现了这个问题。然而,马修的回答并没有帮助我。事实上,我不确定它是否有效。这是因为migrations.RunSQL(...)行实际上并不运行 SQL;它创建类型RunSQL的新对象,它是Command,然后立即丢弃它。

以下是我最终解决问题的方法,以防将来有人试图搜索“django条件迁移”:

from __future__ import unicode_literals

import django.contrib.postgres.fields
from django.db import migrations, models


class PostgresOnlyCreateModel(migrations.CreateModel):
    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        if schema_editor.connection.vendor.startswith("postgres"):
            super(PostgresOnlyCreateModel, self).database_forwards(app_label, schema_editor, from_state, to_state)

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        if schema_editor.connection.vendor.startswith("postgres"):
            super(PostgresOnlyCreateModel, self).database_backwards(app_label, schema_editor, from_state, to_state)


class Migration(migrations.Migration):

    dependencies = [
        ...whatever...
    ]

    operations = [
        PostgresOnlyCreateModel(
            name='...whatever...',
            fields=[...whatever...],
        ),
    ]

答案 3 :(得分:0)

在Migration类中未提供该信息,它在传递给RunPython操作的schema_editor属性中提供。有关使用此功能的一些示例,请参阅the documentation

答案 4 :(得分:0)

另一种选择是让实际的 sql 依赖于 db.connection.vendor:

from django.db import connection

CONCURRENTLY = "CONCURRENTLY" if connection.vendor == "postgres" else ""
SQL = f"CREATE INDEX {CONCURRENTLY}..."

此时您可以只使用 migrations.RunSQL,这很方便,尤其是当您使用 state_operations 参数时。