---
title: "数据库迁移操作"
version: 5.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.2/ref/contrib/postgres/operations/
canonical: https://djangodocs.dev/zh-hans/5.2/ref/contrib/postgres/operations/
---
# 数据库迁移操作

所有这些 [操作](/zh-hans/5.2/ref/migration-operations/) 都可以从 `django.contrib.postgres.operations` 模块中获得。

## 使用迁移创建扩展

你可以使用迁移文件在数据库中创建一个 PostgreSQL 扩展。这个例子创建了一个 hstore 扩展，但同样的原理也适用于其他扩展。

在涉及到 [`HStoreField`](/zh-hans/5.2/ref/contrib/postgres/fields/#django.contrib.postgres.fields.HStoreField) 的第一个 `CreateModel` 或 `AddField` 操作之前，通过添加 [`HStoreExtension`](#django.contrib.postgres.operations.HStoreExtension) 操作的迁移，在 PostgreSQL 中设置 hstore 扩展。例如：

```
from django.contrib.postgres.operations import HStoreExtension

class Migration(migrations.Migration):
    ...

    operations = [HStoreExtension(), ...]
```

如果扩展名已经存在，该操作会跳过添加。

对于大多数扩展来说，这需要一个具有超级用户权限的数据库用户。如果 Django 数据库的用户没有相应的权限，你就必须在 Django 迁移之外用一个有权限的用户创建扩展。在这种情况下，连接到你的 Django 数据库，并运行查询 `CREATE EXTENSION IF NOT EXISTS hstore;`。

## `CreateExtension`

#### `class CreateExtension(name)`

一个安装 PostgreSQL 扩展的 `Operation` 子类。对于普通的扩展，请使用下面一个更具体的子类。

#### `name`

这是一个必要的参数。要安装的扩展名。

## `BloomExtension`

#### `class BloomExtension`

安装 `bloom` 扩展。

## `BtreeGinExtension`

#### `class BtreeGinExtension`

安装 `btree_gin` 扩展。

## `BtreeGistExtension`

#### `class BtreeGistExtension`

安装 `btree_gist` 扩展。

## `CITextExtension`

#### `class CITextExtension`

安装 `citext` 扩展。

## `CryptoExtension`

#### `class CryptoExtension`

安装 `pgcrypto` 扩展。

## `HStoreExtension`

#### `class HStoreExtension`

安装 `hstore` 扩展，并设置连接来解释 hstore 数据，以便在后续迁移中使用。

## `TrigramExtension`

#### `class TrigramExtension`

安装 `pg_trgm` 扩展。

## `UnaccentExtension`

#### `class UnaccentExtension`

安装 `unaccent` 扩展。

## 使用迁移来管理整理

如果你需要使用你的操作系统提供的特定字节序来过滤或排序一个列，但 PostgreSQL 没有提供，你可以使用迁移文件来管理数据库中的字节序。然后，这些字节序可以在 [`CharField`](/zh-hans/5.2/ref/models/fields/#django.db.models.CharField)、[`TextField`](/zh-hans/5.2/ref/models/fields/#django.db.models.TextField) 以及它们的子类上使用 `db_collation` 参数。

例如，为德国电话簿的排序创建一个字节序：

```
from django.contrib.postgres.operations import CreateCollation

class Migration(migrations.Migration):
    ...

    operations = [
        CreateCollation(
            "case_insensitive",
            provider="icu",
            locale="und-u-ks-level2",
            deterministic=False,
        ),
        ...,
    ]
```

#### `class CreateCollation(name, locale, * (Keyword-only parameters separator (PEP 3102)), provider='libc', deterministic=True)`

用给定的 `name`、`locale` 和 `provider` 创建一个字节序。

将 `deterministic` 参数设置为 `False` 以创建一个非确定的字节序，例如用于不区分大小写的过滤。

#### `class RemoveCollation(name, locale, * (Keyword-only parameters separator (PEP 3102)), provider='libc', deterministic=True)`

移除名为 `name` 的字节序。

当反查时，这是用提供的 `locale`、`provider` 和 `deterministic` 参数创建一个字节序。因此，需要 `locale` 来使这个操作可逆。

## 并发索引操作

PostgreSQL 支持 `CREATE INDEX` 和 `DROP INDEX` 语句中的 `CONCURRENTLY` 选项，以增加和删除索引而不锁定写入。这个选项对于在实际生产的数据库中添加或删除索引非常有用。

#### `class AddIndexConcurrently(model_name, index)`

就像 [`AddIndex`](/zh-hans/5.2/ref/migration-operations/#django.db.migrations.operations.AddIndex) 一样，但是使用 `CONCURRENTLY` 选项创建索引。这在使用这个选项时有一些注意事项，参见 [PostgreSQL 关于并发建立索引的文档](https://www.postgresql.org/docs/current/sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY) 。

#### `class RemoveIndexConcurrently(model_name, name)`

就像 [`RemoveIndex`](/zh-hans/5.2/ref/migration-operations/#django.db.migrations.operations.RemoveIndex) 一样，但是使用 `CONCURRENTLY` 选项来删除索引。这在使用这个选项时有一些注意事项，请看 [PostgreSQL 文档](https://www.postgresql.org/docs/current/sql-dropindex.html) 。

> **Note**
>
> 在事务中不支持 `CONCURRENTLY` 选项（见 [非原子性迁移](/zh-hans/5.2/howto/writing-migrations/#non-atomic-migrations)）。

## 添加约束条件而不强制执行验证

PostgreSQL 支持 `NOT VALID` 选项和 `ADD CONSTRAINT` 语句来添加检查约束，而不对现有记录进行验证。如果你想跳过潜在的冗长的表扫描来验证所有现有的记录是否满足约束条件，这个选项很有用。

要在以后的时间点验证用 `NOT VALID` 选项创建的检查约束，请使用 [`ValidateConstraint`](#django.contrib.postgres.operations.ValidateConstraint) 操作。

更多细节请参见 [PostgreSQL 文档](https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-NOTES) 。

#### `class AddConstraintNotValid(model_name, constraint)`

就像 [`AddConstraint`](/zh-hans/5.2/ref/migration-operations/#django.db.migrations.operations.AddConstraint) 一样，但避免了对现有记录进行验证约束。

#### `class ValidateConstraint(model_name, name)`

扫描表并验证现有记录上给定的检查约束。

> **Note**
>
> `AddConstraintNotValid` 和 `ValidateConstraint` 操作应该在两个独立的迁移中执行。在同一个原子迁移中执行这两个操作的效果与 [`AddConstraint`](/zh-hans/5.2/ref/migration-operations/#django.db.migrations.operations.AddConstraint) 相同，而在一个非原子迁移中执行这两个操作，如果 `ValidateConstraint` 操作失败，可能会使数据库处于不一致的状态。
