django db_index迁移是否同时运行?

时间:2015-05-29 14:43:15

标签: django django-south django-migrations

我想添加一个multi-column index to a postgres数据库。我有一个非阻塞SQL命令来执行此操作,如下所示:

.ui-icon-addtochart
{
    content: url(../images/addtochart.jpg) !important;
}

.ui-icon-removefromchart
{
    content: url(../images/removefromchart.jpg) !important;
}

当我将db_index添加到我的模型并运行迁移时,它是否会同时运行还是会阻止写入?是否可以在django中进行并发迁移?

6 个答案:

答案 0 :(得分:7)

使用Django 1.10迁移,您可以使用RunSQL创建并发索引,并通过在迁移时将atomic = False设置为数据属性来使非原子迁移禁用包装事务:

class Migration(migrations.Migration):
    atomic = False # disable transaction

    dependencies = []

    operations = [
        migrations.RunSQL('CREATE INDEX CONCURRENTLY ...')
    ]

答案 1 :(得分:1)

django中不支持PostgreSQL concurent索引创建。

以下是请求此功能的故障单 - https://code.djangoproject.com/ticket/21039

但是,您可以在迁移中手动指定任何自定义RunSQL操作 - https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql

答案 2 :(得分:1)

Django 3.0中有AddIndexConcurrentlyRemoveIndexConcurrently

https://docs.djangoproject.com/en/dev/ref/contrib/postgres/operations/#django.contrib.postgres.operations.AddIndexConcurrently

创建迁移,然后将migrations.AddIndex更改为AddIndexConcurrently。从django.contrib.postgres.operations导入。

答案 3 :(得分:0)

按照tgroshon对新django 1.10 +说的话

对于django的较小版本,我已经使用更详细的子类化方法取得了成功:

from django.db import migrations, models


class RunNonAtomicSQL(migrations.RunSQL):
    def _run_sql(self, schema_editor, sqls):
        if schema_editor.connection.in_atomic_block:
            schema_editor.atomic.__exit__(None, None, None)
        super(RunNonAtomicSQL, self)._run_sql(schema_editor, sqls)


class Migration(migrations.Migration):
    dependencies = [
    ]

    operations = [

        RunNonAtomicSQL(
            "CREATE INDEX CONCURRENTLY",
        )
    ]

答案 4 :(得分:0)

您可以使用SeparateDatabaseAndState迁移操作来提供用于创建索引的自定义SQL命令。该操作接受两个操作列表:

  • state_operations 是要应用于Django模型状态的操作。 它们不会影响数据库。

  • database_operations 是要应用于数据库的操作。

迁移示例如下:

from django.db import migrations, models

class Migration(migrations.Migration):
    atomic = False

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [    
        migrations.SeparateDatabaseAndState(    
            state_operations=[
                # operation generated by `makemigrations` to create an ordinary index
                migrations.AlterField(
                    # ...  
                ),
            ],

            database_operations=[
                # operation to run custom SQL command (check the output of `sqlmigrate`
                # to see the auto-generated SQL, edit as needed)
                migrations.RunSQL(sql='CREATE INDEX CONCURRENTLY ...',
                                  reverse_sql='DROP INDEX ...'),
            ],
        ),
    ]

答案 5 :(得分:0)

你可以做类似的事情


import django.contrib.postgres.indexes
from django.db import migrations, models
from django.contrib.postgres.operations import AddIndexConcurrently


class Migration(migrations.Migration):

    atomic = False

    dependencies = [
        ("app_name", "parent_migration"),
    ]

    operations = [
        AddIndexConcurrently(
            model_name="mymodel",
            index=django.contrib.postgres.indexes.GinIndex(
                fields=["field1"],
                name="field1_idx",
            ),
        ),
        AddIndexConcurrently(
            model_name="mymodel",
            index=models.Index(
                fields=["field2"], name="field2_idx"
            ),
        ),
    ]

参考:https://docs.djangoproject.com/en/dev/ref/contrib/postgres/operations/#django.contrib.postgres.operations.AddIndexConcurrently