=============================
Database migration operations
=============================

All of these :doc:`operations </ref/migration-operations>` are available from
the ``django.contrib.postgres.operations`` module.

.. _create-postgresql-extensions:

Creating extension using migrations
===================================

You can create a PostgreSQL extension in your database using a migration file.
This example creates an hstore extension, but the same principles apply for
other extensions.

Set up the hstore extension in PostgreSQL before the first ``CreateModel``
or ``AddField`` operation that involves
:class:`~django.contrib.postgres.fields.HStoreField` by adding a migration with
the :class:`~django.contrib.postgres.operations.HStoreExtension` operation.
For example::

    from django.contrib.postgres.operations import HStoreExtension

    class Migration(migrations.Migration):
        ...

        operations = [
            HStoreExtension(),
            ...
        ]

The operation skips adding the extension if it already exists.

For most extensions, this requires a database user with superuser privileges.
If the Django database user doesn't have the appropriate privileges, you'll
have to create the extension outside of Django migrations with a user that has
them. In that case, connect to your Django database and run the query
``CREATE EXTENSION IF NOT EXISTS hstore;``.

.. versionchanged:: 3.2

    In older versions, the pre-existence of the extension isn't checked.

.. currentmodule:: django.contrib.postgres.operations

``CreateExtension``
===================

.. class:: CreateExtension(name)

    An ``Operation`` subclass which installs a PostgreSQL extension. For common
    extensions, use one of the more specific subclasses below.

    .. attribute:: name

        This is a required argument. The name of the extension to be installed.

``BloomExtension``
==================

.. class:: BloomExtension()

    .. versionadded:: 3.1

    Installs the ``bloom`` extension.

``BtreeGinExtension``
=====================

.. class:: BtreeGinExtension()

    Installs the ``btree_gin`` extension.

``BtreeGistExtension``
======================

.. class:: BtreeGistExtension()

    Installs the ``btree_gist`` extension.

``CITextExtension``
===================

.. class:: CITextExtension()

    Installs the ``citext`` extension.

``CryptoExtension``
===================

.. class:: CryptoExtension()

    Installs the ``pgcrypto`` extension.

``HStoreExtension``
===================

.. class:: HStoreExtension()

    Installs the ``hstore`` extension and also sets up the connection to
    interpret hstore data for possible use in subsequent migrations.

``TrigramExtension``
====================

.. class:: TrigramExtension()

    Installs the ``pg_trgm`` extension.

``UnaccentExtension``
=====================

.. class:: UnaccentExtension()

    Installs the ``unaccent`` extension.

.. _manage-postgresql-collations:

Managing collations using migrations
====================================

.. versionadded:: 3.2

If you need to filter or order a column using a particular collation that your
operating system provides but PostgreSQL does not, you can manage collations in
your database using a migration file. These collations can then be used with
the ``db_collation`` parameter on :class:`~django.db.models.CharField`,
:class:`~django.db.models.TextField`, and their subclasses.

For example, to create a collation for German phone book ordering::

    from django.contrib.postgres.operations import CreateCollation

    class Migration(migrations.Migration):
        ...

        operations = [
            CreateCollation(
                'german_phonebook',
                provider='icu',
                locale='und-u-ks-level2',
            ),
            ...
        ]

.. class:: CreateCollation(name, locale, *, provider='libc', deterministic=True)

    Creates a collation with the given ``name``, ``locale`` and ``provider``.

    Set the ``deterministic`` parameter to ``False`` to create a
    non-deterministic collation, such as for case-insensitive filtering.

.. class:: RemoveCollation(name, locale, *, provider='libc', deterministic=True)

    Removes the collations named ``name``.

    When reversed this is creating a collation with the provided ``locale``,
    ``provider``, and ``deterministic`` arguments. Therefore, ``locale`` is
    required to make this operation reversible.

.. admonition:: Restrictions

    PostgreSQL 9.6 only supports the ``'libc'`` provider.

    Non-deterministic collations are supported only on PostgreSQL 12+.

Concurrent index operations
===========================

PostgreSQL supports the ``CONCURRENTLY`` option to ``CREATE INDEX`` and
``DROP INDEX`` statements to add and remove indexes without locking out writes.
This option is useful for adding or removing an index in a live production
database.

.. class:: AddIndexConcurrently(model_name, index)

    Like :class:`~django.db.migrations.operations.AddIndex`, but creates an
    index with the ``CONCURRENTLY`` option. This has a few caveats to be aware
    of when using this option, see `the PostgreSQL documentation of building
    indexes concurrently <https://www.postgresql.org/docs/current/
    sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY>`_.

.. class:: RemoveIndexConcurrently(model_name, name)

    Like :class:`~django.db.migrations.operations.RemoveIndex`, but removes the
    index with the ``CONCURRENTLY`` option. This has a few caveats to be aware
    of when using this option, see `the PostgreSQL documentation
    <https://www.postgresql.org/docs/current/sql-dropindex.html>`_.

.. note::

    The ``CONCURRENTLY`` option is not supported inside a transaction (see
    :ref:`non-atomic migration <non-atomic-migrations>`).
