django db_index 并发迁移 运行 吗?
Do django db_index migrations run concurrently?
我想添加一个 multi-column index to a postgres 数据库。我有一个非阻塞 SQL 命令来执行此操作,如下所示:
CREATE INDEX CONCURRENTLY shop_product_fields_index ON shop_product (id, ...);
当我将 db_index 添加到我的模型并 运行 迁移时,它会同时 运行 还是会阻止写入?在 Django 中是否可以并发迁移?
django 不支持 PostgreSQL 并发索引创建。
这是请求此功能的工单 - https://code.djangoproject.com/ticket/21039
但是,您可以在迁移中手动指定任何自定义 RunSQL 操作 -
https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql
使用 Django 1.10 迁移,您可以使用 RunSQL
创建并发索引,并通过将 atomic = False
设置为迁移的数据属性使迁移成为非原子的来禁用包装事务:
class Migration(migrations.Migration):
atomic = False # disable transaction
dependencies = []
operations = [
migrations.RunSQL('CREATE INDEX CONCURRENTLY ...')
]
按照 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",
)
]
您可以使用 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 ...'),
],
),
]
Django 3.0中有AddIndexConcurrently
和RemoveIndexConcurrently
:
创建迁移,然后将 migrations.AddIndex
更改为 AddIndexConcurrently
。从 django.contrib.postgres.operations
.
导入
你可以这样做
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"
),
),
]
我想添加一个 multi-column index to a postgres 数据库。我有一个非阻塞 SQL 命令来执行此操作,如下所示:
CREATE INDEX CONCURRENTLY shop_product_fields_index ON shop_product (id, ...);
当我将 db_index 添加到我的模型并 运行 迁移时,它会同时 运行 还是会阻止写入?在 Django 中是否可以并发迁移?
django 不支持 PostgreSQL 并发索引创建。
这是请求此功能的工单 - https://code.djangoproject.com/ticket/21039
但是,您可以在迁移中手动指定任何自定义 RunSQL 操作 - https://docs.djangoproject.com/en/1.8/ref/migration-operations/#runsql
使用 Django 1.10 迁移,您可以使用 RunSQL
创建并发索引,并通过将 atomic = False
设置为迁移的数据属性使迁移成为非原子的来禁用包装事务:
class Migration(migrations.Migration):
atomic = False # disable transaction
dependencies = []
operations = [
migrations.RunSQL('CREATE INDEX CONCURRENTLY ...')
]
按照 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",
)
]
您可以使用 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 ...'),
],
),
]
Django 3.0中有AddIndexConcurrently
和RemoveIndexConcurrently
:
创建迁移,然后将 migrations.AddIndex
更改为 AddIndexConcurrently
。从 django.contrib.postgres.operations
.
你可以这样做
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"
),
),
]