---
title: "マイグレーション操作"
version: 2.1
locale: ja
source: https://docs.djangoproject.com/ja/2.1/ref/migration-operations/
canonical: https://djangodocs.dev/ja/2.1/ref/migration-operations/
---
# マイグレーション操作

マイグレーションファイルは一つ以上の `オペレーション`、データベースに対してマイグレーションが行うべき操作を宣言的に保持するオブジェクト、から構成されます。

加えて Django はモデルが過去からどのように変遷したかを解明するため、またマイグレーションを自動的に記述できるように最後のマイグレーション以降モデルに対して行われた変更を導出するために、これらの `オペレーション` オブジェクトを利用します;マイグレーションの定義が宣言的であるのはそのためで、これは Django がプロジェクトの全容がどういった物であるかを解析する際、データベースを直接操作することなく、容易にマイグレーション定義を全てメモリ上にロードして処理できる事を意味します。

[データのマイグレーション](/ja/2.1/topics/migrations/#data-migrations) や高度なデータベースへの手動操作のような特別な `オペレーション` も存在します。もし頻繁に行われる独自の変更をカプセル化したければ独自に `オペレーション` を記述する事もできます。

もし独自の `Operation` オブジェクトを定義する空のマイグレーションファイルが必要であれば、`python manage.py makemigrations --empty yourappname` を実行するだけですが、手動でのスキーマ変更操作の追加はマイグレーションの自動検出機構の誤動作を招き、[`makemigrations`](/ja/2.1/ref/django-admin/#django-admin-makemigrations) を実行した出力結果が正常な物でなくなる可能性が有る事に十分注意してください。

Django が提供するコア機能は全て `django.db.migrations.operations` モジュールから利用できます。

より入門的な内容に関しては、 [トピックスのマイグレーション](/ja/2.1/topics/migrations/) を参照ください。

## スキーマ操作

### `CreateModel`

#### `class CreateModel(name, fields, options=None, bases=None, managers=None)`

プロジェクトの履歴に新たなモデル、そしてデータベース上に対応するテーブルを作成します。

`name` は `models.py` ファイルに定義されているであろうモデルの名称です。

`fields` は `(フィールド名, フィールドのインスタンス)` という 2 値のタプルのリストです。フィールドのインスタンスは束縛されないフィールド(他のモデルから取得した物でなく、単に `models.CharField(...)` 等と記述する物)でなければいけません。

`options` は定義されるモデルの `Meta` クラスの値からなるオプションの辞書オブジェクトです。

`bases` は定義するモデルが継承する他のクラスのリストです;このリストは定義するモデルが他のモデルに依存する(履歴上のバージョンを継承する)場合、クラスオブジェクトを文字列として `"appname.ModelName"` という形式で含むことができます。このパラメータが空である場合、定義するモデルは標準の `models.Model` からの継承だけというデフォルト設定を利用します。

`managers` は `(マネージャ名, マネージャのインスタンス)` という 2 値のタプルのリストを受け取ります。マイグレーションの間はリスト内で最初に定義されたマネージャがこのモデルの標準マネージャとして利用されます。

### `DeleteModel`

#### `class DeleteModel(name)`

プロジェクトの履歴からモデルを、加えてデータベースから該当モデルを扱うテーブルを削除します。

### `RenameModel`

#### `class RenameModel(old_name, new_name)`

モデルの名称を今までの名称から新しい名称に変更します。

一度に定義しているモデルの名前とかなり多くのフィールドの名前を変更した場合は手動でこの処理を追加する必要があるかもしれません;マイグレーションの自動検知機構が古い名称を持ったモデルを削除して異なった名称のモデルを追加したと認識してしまうため、そのマイグレーション処理は古いテーブルの全てのデータを消去してしまいます。

### `AlterModelTable`

#### `class AlterModelTable(name, table)`

定義しているモデルのテーブル名を変更します(`Meta` サブクラスの [`db_table`](/ja/2.1/ref/models/options/#django.db.models.Options.db_table) オプションを参照します)。

### `AlterUniqueTogether`

#### `class AlterUniqueTogether(name, unique_together)`

Changes the model's set of unique constraints (the
[`unique_together`](/ja/2.1/ref/models/options/#django.db.models.Options.unique_together) option on the `Meta`
subclass).

### `AlterIndexTogether`

#### `class AlterIndexTogether(name, index_together)`

Changes the model's set of custom indexes (the
[`index_together`](/ja/2.1/ref/models/options/#django.db.models.Options.index_together) option on the `Meta`
subclass).

### `AlterOrderWithRespectTo`

#### `class AlterOrderWithRespectTo(name, order_with_respect_to)`

Makes or deletes the `_order` column needed for the
[`order_with_respect_to`](/ja/2.1/ref/models/options/#django.db.models.Options.order_with_respect_to) option on the `Meta`
subclass.

### `AlterModelOptions`

#### `class AlterModelOptions(name, options)`

Stores changes to miscellaneous model options (settings on a model's `Meta`)
like `permissions` and `verbose_name`. Does not affect the database, but
persists these changes for [`RunPython`](#django.db.migrations.operations.RunPython) instances to use. `options`
should be a dictionary mapping option names to values.

### `AlterModelManagers`

#### `class AlterModelManagers(name, managers)`

Alters the managers that are available during migrations.

### `AddField`

#### `class AddField(model_name, name, field, preserve_default=True)`

Adds a field to a model. `model_name` is the model's name, `name` is
the field's name, and `field` is an unbound Field instance (the thing
you would put in the field declaration in `models.py` \- for example,
`models.IntegerField(null=True)`.

The `preserve_default` argument indicates whether the field's default
value is permanent and should be baked into the project state (`True`),
or if it is temporary and just for this migration (`False`) - usually
because the migration is adding a non-nullable field to a table and needs
a default value to put into existing rows. It does not affect the behavior
of setting defaults in the database directly - Django never sets database
defaults and always applies them in the Django ORM code.

### `RemoveField`

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

Removes a field from a model.

Bear in mind that when reversed, this is actually adding a field to a model.
The operation is reversible (apart from any data loss, which of course is
irreversible) if the field is nullable or if it has a default value that can be
used to populate the recreated column. If the field is not nullable and does
not have a default value, the operation is irreversible.

### `AlterField`

#### `class AlterField(model_name, name, field, preserve_default=True)`

Alters a field's definition, including changes to its type,
[`null`](/ja/2.1/ref/models/fields/#django.db.models.Field.null), [`unique`](/ja/2.1/ref/models/fields/#django.db.models.Field.unique),
[`db_column`](/ja/2.1/ref/models/fields/#django.db.models.Field.db_column) and other field attributes.

The `preserve_default` argument indicates whether the field's default
value is permanent and should be baked into the project state (`True`),
or if it is temporary and just for this migration (`False`) - usually
because the migration is altering a nullable field to a non-nullable one and
needs a default value to put into existing rows. It does not affect the
behavior of setting defaults in the database directly - Django never sets
database defaults and always applies them in the Django ORM code.

Note that not all changes are possible on all databases - for example, you
cannot change a text-type field like `models.TextField()` into a number-type
field like `models.IntegerField()` on most databases.

### `RenameField`

#### `class RenameField(model_name, old_name, new_name)`

Changes a field's name (and, unless [`db_column`](/ja/2.1/ref/models/fields/#django.db.models.Field.db_column)
is set, its column name).

### `AddIndex`

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

Creates an index in the database table for the model with `model_name`.
`index` is an instance of the [`Index`](/ja/2.1/ref/models/indexes/#django.db.models.Index) class.

### `RemoveIndex`

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

Removes the index named `name` from the model with `model_name`.

## 特別な操作

### `RunSQL`

#### `class RunSQL(sql, reverse_sql=None, state_operations=None, hints=None, elidable=False)`

データベース上で任意の SQL を実行させる事ができます - データベースバックエンドで Django が直接サポートしていない先進機能、例えば部分インデックス等、を利用する上で有用です。

`sql` および、与えられれば `reverse_sql` もデータベース上で実行するための SQL 文字列である必要が有ります。多くの(PostgreSQL を除いた)データベースバックエンドにおいて、Django は与えられた SQL を実行前に独立した句で分割します。この処理は Python の [sqlparse](https://pypi.org/project/sqlparse/) ライブラリを必要とします。

文字列もしくは 2 値のタプルのリストを渡すことができます。その内後者はクエリとパラメータを [cursor.execute()](/ja/2.1/topics/db/sql/#executing-custom-sql) において行うのと同じ形式で渡すために用いられます。以下の 3 つの処理は互いに等価です:

```
migrations.RunSQL("INSERT INTO musician (name) VALUES ('Reinhardt');")
migrations.RunSQL([("INSERT INTO musician (name) VALUES ('Reinhardt');", None)])
migrations.RunSQL([("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])])
```

クエリにパーセント文字リテラルを含ませたい場合、パラメータを渡していればパーセント文字を二重に記述する必要が有ります。

`reverse_sql` クエリはマイグレーションが非適用となった場合に実行され、前のクエリで行われた変更を取り消す事ができます:

```
migrations.RunSQL(
    [("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
    [("DELETE FROM musician where name=%s;", ['Reinhardt'])],
)
```

引数 `state_operations` にはプロジェクトのステートから見た SQL と等価となる処理を渡すことができます;例えば、手動でカラムを作成した場合、マイグレーションの自動検知機構が最新のモデルのステートを保持できるように `AddField` のリストを渡す必要が有ります(そうしなければ、次に `makemigrations` を実行した際、フィールドを追加した処理を一切検知せずに同じ追加処理を再度適用してしまうでしょう)。例として:

```
migrations.RunSQL(
    "ALTER TABLE musician ADD COLUMN name varchar(255) NOT NULL;",
    state_operations=[
        migrations.AddField(
            'musician',
            'name',
            models.CharField(max_length=255),
        ),
    ],
)
```

オプションの `hints` 引数はデータベースルータオブジェクトの [`allow_migrate()`](/ja/2.1/topics/db/multi-db/#allow_migrate) メソッドに `**hints` として渡されてルーティングの決定を補助します。データベースのヒントに関しての詳細は [Hints](/ja/2.1/topics/db/multi-db/#topics-db-multi-db-hints) を参照ください。

オプションの `elidable` 引数はこの処理を [マイグレーションの統合](/ja/2.1/topics/migrations/#migration-squashing) を行った際に消去する(省略する)か否かを決定します。

#### `RunSQL.noop`

指定された順序での処理を行わない場合、`sql` もしくは `reverse_sql` に対して `RunSQL.noop` 要素を渡します。これは特に処理を逆の順序で行いたい場合に有用です。

### `RunPython`

#### `class RunPython(code, reverse_code=None, atomic=None, hints=None, elidable=False)`

マイグレーション履歴を反映して独自の Python コードを実行します。`code` (与えられれば加えて `reverse_code` )は二つの引数を受け取る呼び出し可能オブジェクトでなければなりません;第一引数はプロジェクトの履歴において処理の場所が一致している履歴を反映したモデルを含んだ `django.apps.registry.Apps` のインスタンスであり、第二引数は [`SchemaEditor`](/ja/2.1/ref/schema-editor/#django.db.backends.base.schema.BaseDatabaseSchemaEditor) のインスタンスです。

`reverse_code` 引数はマイグレーションが非適用となった際に呼び出されます。この呼び出し可能オブジェクトはマイグレーションが逆順処理可能となるよう、先の呼び出し可能オブジェクト `code` で行われた処理を無効化しなければなりません。

オプションの `hints` 引数はルーティングの決定を補助するためにデータベースルータの [`allow_migrate()`](/ja/2.1/topics/db/multi-db/#allow_migrate) メソッドに `**hints` として渡されます。データベースのヒントに関しての詳細は [Hints](/ja/2.1/topics/db/multi-db/#topics-db-multi-db-hints) を参照してください。

オプションの `elidable` 引数はこの処理を [マイグレーションの統合](/ja/2.1/topics/migrations/#migration-squashing) を行った際に消去する(省略する)か否かを決定します。

上記マイグレーションファイル内の `Migration` クラスにおいてコードが分割された関数として記述され、単に `RunPython` に渡すだけで良い状態にすることが推奨されます。以下に `RunPython` を用いて `Country` モデル上の初期オブジェクトを追加する例を示します:

```
from django.db import migrations

def forwards_func(apps, schema_editor):
    # We get the model from the versioned app registry;
    # if we directly import it, it'll be the wrong version
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).bulk_create([
        Country(name="USA", code="us"),
        Country(name="France", code="fr"),
    ])

def reverse_func(apps, schema_editor):
    # forwards_func() creates two Country instances,
    # so reverse_func() should delete them.
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).filter(name="USA", code="us").delete()
    Country.objects.using(db_alias).filter(name="France", code="fr").delete()

class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.RunPython(forwards_func, reverse_func),
    ]
```

これは [データのマイグレーション](/ja/2.1/topics/migrations/#data-migrations) の作成、独自のデータ更新と構成変更、そして ORM や Python のコードにアクセスを必要とするあらゆる操作のために行われる一般的な操作です。

もし South マイグレーションツールから移行した場合、これは基本的に処理として South の方式を用いています - 即ち順序通りおよび逆順のマイグレーションに対して 1 つもしくは 2 つのメソッドを用い、ORM とスキーマの操作が可能になるという方式です。多くの場合、South による `orm.Model` もしくは `orm["appname", "Model"]` に対する参照は、本マイグレーションツールによる `apps.get_model("appname", "Model")` に対する参照に直接置き換えて考える事ができ、残りのコードの大半はデータのマイグレーションに際して変更が不要です。しかしながら、他のアプリケーション内のマイグレーションが本アプリケーションの依存関係に組み込まれない限り `apps` は本アプリケーション内のモデルへの参照のみを持ちます。

[`RunSQL`](#django.db.migrations.operations.RunSQL) と同様、もし内部のスキーマを変更する場合は Django のモデル機構のスコープ範囲外(例えば triggers 等)で行うか、もしくはモデルの状態に変更を反映する処理に [`SeparateDatabaseAndState`](#django.db.migrations.operations.SeparateDatabaseAndState) を追加する事を心がけてください - そうでなければ、バージョン管理された ORM およびマイグレーションの自動検出機構が正常に動作しなくなります。

標準では `RunPython` は DDL トランザクションをサポートしないデータベース(例えば MySQL と Oracle 等)上では通常のトランザクション内で記述された内容の処理を行います。この仕組みは安全ではありますが、これらのデータベースバックエンドを利用中に `schema_editor` を利用しようとするとクラッシュを引き起こす場合が有ります;このような場合は、`RunPython` に対して `atomic=False` を渡してください。

トランザクション中の DDL 使用をサポートしているデータベース(SQLite や PostgreSQL)においては、`RunPython` は各マイグレーションに対して作成されたトランザクション以外に自動的にトランザクションを保持しません。そのため、例えば PostgreSQL では、スキーマ変更と `RunPython` を同一のマイグレーション内で結合させて用いるのは避けるべきであり、そうしなければ `OperationalError: cannot ALTER TABLE "mytable" because it has pending trigger events` のようなエラーに遭遇する可能性が有ります。

もしここまでに挙げられた物と異なるデータベースを利用しておりトランザクション中の DDL 事項をサポートしているか不明な場合、 `django.db.connection.features.can_rollback_ddl` 属性を確認してください。

もし `RunPython` 操作が [非アトミックなマイグレーション](/ja/2.1/howto/writing-migrations/#non-atomic-migrations) の一部である場合、その操作は `RunPython` 操作に対して `atomic=True` が渡されて生成されたトランザクション中においてのみ実行されます。

> **Warning**
>
> `RunPython` はモデルのデータベース接続を魔法のように切り替える事はしません;データベースのエイリアス(作成した関数の第二引数 `schema_editor` 内、 `schema_editor.connection.alias` から利用可能)を指定していないモデルのメソッドはすべてデフォルトのデータベースを利用します。

#### `static RunPython.noop()`

指定された順序で処理を行いたくない場合は `code` もしくは `reverse_code` に `RunPython.noop` メソッドを渡してください。この指定は処理を逆順で行いたい場合に特に有用です。

### `SeparateDatabaseAndState`

#### `class SeparateDatabaseAndState(database_operations=None, state_operations=None)`

作業の観点からデータベース(スキーマ変更)と状態(自動検知機構による)を組み合わせて併用する、高度に特殊化された処理です。

It accepts two lists of operations, and when asked to apply state will use the
state list, and when asked to apply changes to the database will use the database
list. Do not use this operation unless you're very sure you know what you're doing.

## 自分で操作を書く

オペレーションは比較的シンプルな API を持っており、Django に内蔵された機能を独自に補助する処理を簡単に記述できるよう設計されています。`Operation` の基本構造は以下のようなものです:

```
from django.db.migrations.operations.base import Operation

class MyCustomOperation(Operation):

    # If this is False, it means that this operation will be ignored by
    # sqlmigrate; if true, it will be run and the SQL collected for its output.
    reduces_to_sql = False

    # If this is False, Django will refuse to reverse past this operation.
    reversible = False

    def __init__(self, arg1, arg2):
        # Operations are usually instantiated with arguments in migration
        # files. Store the values of them on self for later use.
        pass

    def state_forwards(self, app_label, state):
        # The Operation should take the 'state' parameter (an instance of
        # django.db.migrations.state.ProjectState) and mutate it to match
        # any schema changes that have occurred.
        pass

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        # The Operation should use schema_editor to apply any changes it
        # wants to make to the database.
        pass

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        # If reversible is True, this is called when the operation is reversed.
        pass

    def describe(self):
        # This is used to describe what the operation does in console output.
        return "Custom Operation"
```

上の例をテンプレートとして利用する事ができますが、`django.db.migrations.operations` 内の Django 内蔵のオペレーションを参考にする事もできます - これらは `ProjectState` のような半内部的側面を持つマイグレーションフレームワークとその履歴上のモデルを取得する方法、同様に `ModelState` が `state_forwards()` によってその履歴上のモデルを模倣する方法等の可読性が高く広範にわたる例を持っています。

いくつかの注意すべき点

- 単純なマイグレーションについて記述するだけであれば `ProjectState` について多くを学ぶ必要は有りません; ただそれがアプリケーションの(それに対して `get_model` を呼ぶことができる)登録情報へのアクセスを提供するプロパティ `app` を持っている事だけ知っていて下さい。
- `database_forwards` および `database_backwards` は共にパラメータとして 2 つの状態を受け取ります; これらは単に適用される事になる `state_forwards` メソッドの差異を表しているだけですが、利便性と実行速度のために渡されます。
- If you want to work with model classes or model instances from the
  `from_state` argument in `database_forwards()` or
  `database_backwards()`, you must render model states using the
  `clear_delayed_apps_cache()` method to make related models available:

  ```
  def database_forwards(self, app_label, schema_editor, from_state, to_state):
      # This operation should have access to all models. Ensure that all models are
      # reloaded in case any are delayed.
      from_state.clear_delayed_apps_cache()
      ...
  ```
- database\_backwards メソッドにおける `to_state` は *古い* 状態を示します;そのため、その値はマイグレーションが状態を戻した場合は現在の状態となります。
- 内蔵されたオペレーションにおいて `references_model` が実装されているのを見つけるかもしれません;これは独自のオペレーションのためでなく自動検知機構のコードの一部として存在しています。

> **Warning**
>
> パフォーマンス上の理由から、`ModelState.fields` 内の [`Field`](/ja/2.1/ref/models/fields/#django.db.models.Field) のインスタンスはマイグレーション間で再利用されます。これらのインスタンスの属性を決して変更してはいけません。`state_forwards()` 内のフィールドを変更したい場合は、`ModelState.fields` から古いインスタンスを削除して新たなインスタンスと置き換える必要が有ります。`ModelState.managers` 内の [`Manager`](/ja/2.1/topics/db/managers/#django.db.models.Manager) のインスタンスについても同様です。

簡単な例として、(PostgreSQL のより興味深い機能を含んだ) PostgreSQL 拡張をロードするオペレーションを作成してみましょう。これはかなり単純な物となります;モデルの状態を変えず、1 つのコマンドを実行するだけです:

```
from django.db.migrations.operations.base import Operation

class LoadExtension(Operation):

    reversible = True

    def __init__(self, name):
        self.name = name

    def state_forwards(self, app_label, state):
        pass

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        schema_editor.execute("CREATE EXTENSION IF NOT EXISTS %s" % self.name)

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        schema_editor.execute("DROP EXTENSION %s" % self.name)

    def describe(self):
        return "Creates extension %s" % self.name
```
